package com.xbongbong.saas.service.impl;/*/*/

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.business.rule.RuleBusinessLogger;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DefaultTypeEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.DefaultAttrPoJo;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.MultiUnitItemPoJo;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FormDataValidateProductHelp;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.help.ProSaveHelp;
import com.xbongbong.paas.help.TransactionHelp;
import com.xbongbong.paas.help.UserHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.pojo.InfoArrPojo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasProcessTemplateModel;
import com.xbongbong.paas.pojo.AttrValuePojo;
import com.xbongbong.paas.pojo.ButtonPojo;
import com.xbongbong.paas.pojo.FieldAttrEntityForImport;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataDeleteBatchDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.dto.ImportFormDataDTO;
import com.xbongbong.paas.pojo.dto.ParseSingleRowDataDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.dto.UserAndDepartmentGetDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.imports.CellTitlePojo;
import com.xbongbong.paas.pojo.imports.RowGroupPojo;
import com.xbongbong.paas.pojo.vo.ParseSingleRowDataVO;
import com.xbongbong.paas.pojo.vo.UserAndDepartmentGetVO;
import com.xbongbong.parent.interfaces.DynamicStrategy;
import com.xbongbong.paas.service.dynamic.crm.strategy.DynamicStrategyFactory;
import com.xbongbong.paas.service.team.TeamDataHelp;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.PageHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.RoleSimpleVO;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.ItemUtil;
import com.xbongbong.parent.parse.data.FormDataUpdateGetAnalysisDataHelp;
import com.xbongbong.pro.appdetail.pojo.MobileDetailDialPhonePojo;
import com.xbongbong.pro.applist.pojo.AppListPojo;
import com.xbongbong.pro.applist.pojo.vo.ListAppVO;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.businessproduct.pojo.dto.BusinessProductListDTO;
import com.xbongbong.pro.businessproduct.pojo.vo.BusinessProductListVO;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.detailtab.vo.DetailTabGetVO;
import com.xbongbong.pro.detailtab.vo.ProductSummaryVO;
import com.xbongbong.pro.domain.entity.LinkProductRelyEntity;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicDeleteDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicSaveDTO;
import com.xbongbong.pro.enums.DetailTabStatusColorEnum;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.ProErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.TemplateErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.WorkOrderErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.formdata.pojo.dto.SaasAnalysisDataDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainInLinkItemDTO;
import com.xbongbong.pro.listbatch.pojo.dto.AddLabelDTO;
import com.xbongbong.pro.log.pojo.dto.RuleBusinessLogDTO;
import com.xbongbong.pro.message.constant.WorkOrderPushConstant;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.help.PushHelper;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.product.pojo.ProductSavePojo;
import com.xbongbong.pro.product.pojo.dto.PagingProductDTO;
import com.xbongbong.pro.product.pojo.vo.DetailProductVO;
import com.xbongbong.pro.product.pojo.vo.PagingProductVO;
import com.xbongbong.pro.rabbitmq.producer.BaseProducer;
import com.xbongbong.pro.warehouse.pojo.dto.ProductWarehouseMapDTO;
import com.xbongbong.pro.warehouse.pojo.vo.ProductWarehouseMapVO;
import com.xbongbong.pro.workorder.pojo.CreateNodeReturnPojo;
import com.xbongbong.pro.workorder.pojo.TimeConsumingOutPojo;
import com.xbongbong.pro.workorder.pojo.dto.ChangeWorkflowItemDTO;
import com.xbongbong.pro.workorder.pojo.dto.WorkOrderDeleteBatchDTO;
import com.xbongbong.pro.workorder.pojo.dto.WorkOrderEditAttrUpdateDTO;
import com.xbongbong.pro.workorder.pojo.dto.WorkOrderRestoreOutboundDTO;
import com.xbongbong.pro.workorder.pojo.dto.WorkOrderUpdateBatchDTO;
import com.xbongbong.pro.workorder.pojo.dto.WorkOrderUpdateByBusinessRuleDTO;
import com.xbongbong.pro.workorder.pojo.dto.WorkOrderUpdateDTO;
import com.xbongbong.pro.workorder.pojo.vo.WorkOrderChangeFlowItemVO;
import com.xbongbong.pro.workorder.pojo.vo.WorkOrderDeleteBatchVO;
import com.xbongbong.pro.workorder.pojo.vo.WorkOrderEditAttrUpdateVO;
import com.xbongbong.pro.workorder.pojo.vo.WorkOrderOutstockDeleteVO;
import com.xbongbong.pro.workorder.pojo.vo.WorkOrderUpdateBatchVO;
import com.xbongbong.pro.workorder.pojo.vo.WorkOrderUpdateByBusinessRuleVO;
import com.xbongbong.saas.analytical.impl.WorkOrderValidateAnalyticalServiceImpl;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.ProductConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.constant.TabConstant;
import com.xbongbong.saas.domain.entity.OutstockProductEntity;
import com.xbongbong.saas.domain.entity.ProductStockInfoEntity;
import com.xbongbong.saas.domain.entity.WorkOrderCcEntity;
import com.xbongbong.saas.domain.entity.WorkOrderEntity;
import com.xbongbong.saas.domain.entity.WorkOrderEvaluateEntity;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.domain.entity.WorkOrderFlowNodeEntity;
import com.xbongbong.saas.domain.entity.WorkOrderFlowUserEntity;
import com.xbongbong.saas.domain.entity.WorkOrderProductEntity;
import com.xbongbong.saas.domain.entity.WorkOrderStageEntity;
import com.xbongbong.saas.domain.entity.WorkOrderTemplateEntity;
import com.xbongbong.saas.domain.entity.ext.ProductEntityExt;
import com.xbongbong.saas.domain.entity.ext.WorkOrderEntityExt;
import com.xbongbong.saas.enums.BusinessProductEnum;
import com.xbongbong.saas.enums.ListGroupEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperatePageEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.OutstockTypeEnum;
import com.xbongbong.saas.enums.ProjectLogEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.RelativeProductEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.UpdateDataTypeEnum;
import com.xbongbong.saas.enums.WorkOrderEmergencyEnum;
import com.xbongbong.saas.enums.WorkOrderFlowNodeTypeEnum;
import com.xbongbong.saas.enums.WorkOrderNodeStatusEnum;
import com.xbongbong.saas.enums.WorkOrderStageOperationEnum;
import com.xbongbong.saas.enums.WorkOrderStageRobTypeEnum;
import com.xbongbong.saas.enums.WorkOrderStageRuleEnum;
import com.xbongbong.saas.enums.WorkOrderStatusEnum;
import com.xbongbong.saas.enums.WorkOrderTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.enums.dictionary.WorkOrderShipStatusEnum;
import com.xbongbong.saas.enums.product.WorkOrderProductEnum;
import com.xbongbong.saas.help.ExplainHelp;
import com.xbongbong.saas.help.LogHandleHelp;
import com.xbongbong.saas.help.RelativeProductHelp;
import com.xbongbong.saas.help.SaasSaveHelp;
import com.xbongbong.saas.help.SaasUpdateHelp;
import com.xbongbong.saas.help.workflow.WorkOrderHelp;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.LinkProductRelyModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.model.SpecificationModel;
import com.xbongbong.saas.model.WorkOrderCcModel;
import com.xbongbong.saas.model.WorkOrderEvaluateModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.model.WorkOrderFlowNodeModel;
import com.xbongbong.saas.model.WorkOrderFlowUserModel;
import com.xbongbong.saas.model.WorkOrderModel;
import com.xbongbong.saas.model.WorkOrderProductModel;
import com.xbongbong.saas.model.WorkOrderStageModel;
import com.xbongbong.saas.model.WorkOrderTemplateModel;
import com.xbongbong.saas.service.BusinessProductService;
import com.xbongbong.saas.service.MobileDetailService;
import com.xbongbong.saas.service.OpportunityService;
import com.xbongbong.saas.service.OutstockService;
import com.xbongbong.saas.service.ProductService;
import com.xbongbong.saas.service.UserTeamService;
import com.xbongbong.saas.service.WarehouseService;
import com.xbongbong.saas.service.WorkOrderCcService;
import com.xbongbong.saas.service.WorkOrderProductService;
import com.xbongbong.saas.service.WorkOrderService;
import com.xbongbong.saas.service.toolbox.help.AttrDecimalPrecisionHelper;
import com.xbongbong.saas.service.toolbox.help.LogHelp;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.enums.RoleEnum;
import com.xbongbong.sys.help.ProPermissionHelp;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.workorder.service.WorkOrderBasicService;
import com.xbongbong.workorder.service.WorkOrderFlowUserService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.stream.Collectors;

import static com.xbongbong.saas.enums.RelativeProductEnum.BARCODE;
import static com.xbongbong.saas.enums.RelativeProductEnum.BATCH;
import static com.xbongbong.saas.enums.RelativeProductEnum.COST;
import static com.xbongbong.saas.enums.RelativeProductEnum.GUARANTEE_PERIOD;
import static com.xbongbong.saas.enums.RelativeProductEnum.MEMO;
import static com.xbongbong.saas.enums.RelativeProductEnum.NAME;
import static com.xbongbong.saas.enums.RelativeProductEnum.NUM;
import static com.xbongbong.saas.enums.RelativeProductEnum.PRODUCE_DATE;
import static com.xbongbong.saas.enums.RelativeProductEnum.PRODUCT_NO;
import static com.xbongbong.saas.enums.RelativeProductEnum.PRODUCT_PRICE;
import static com.xbongbong.saas.enums.RelativeProductEnum.SPECIFICATION;
import static com.xbongbong.saas.enums.RelativeProductEnum.STOCK;
import static com.xbongbong.saas.enums.RelativeProductEnum.UNIT;
import static com.xbongbong.saas.enums.RelativeProductEnum.WAREHOUSE;
import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;


/**
 *
 * @author 魏荣杰
 * @date 2019/3/21 14:19
 * @since v1.0
 * @version v1.0
 */
@Service("workOrderService")
public class WorkOrderServiceImpl implements WorkOrderService {
    private static final Logger LOG = LoggerFactory.getLogger(WorkOrderServiceImpl.class);

    @Resource
    private SaasSaveHelp saasSaveHelp;
    @Resource
    private OutstockService outstockService;
    @Resource
    private SaasUpdateHelp saasUpdateHelp;
    @Resource
    private WorkOrderTemplateModel workOrderTemplateModel;
    @Resource
    private WorkOrderStageModel workOrderStageModel;
    @Resource
    private WorkOrderModel workOrderModel;
    @Resource
    private WorkOrderBasicService workOrderBasicService;
    @Resource
    private WorkOrderFlowNodeModel workOrderFlowNodeModel;
    @Resource
    private UserModel userModel;
    @Resource
    private BaseProducer baseProducer;
    @Resource
    private PushHelper pushHelper;
    @Resource
    private WorkOrderCcService workOrderCcService;
    @Resource
    private WorkOrderFlowUserService workOrderFlowUserService;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private WorkOrderProductModel workOrderProductModel;
    @Resource
    private ProductModel productModel;
    @Resource
    private AttrDecimalPrecisionHelper attrDecimalPrecisionHelper;
    @Resource
    private SpecificationModel specificationModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private ProductService productService;
    @Resource
    private ExplainHelp explainHelp;
    @Resource
    private WarehouseService warehouseService;
    @Resource
    private WorkOrderEvaluateModel workOrderEvaluateModel;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private WorkOrderFlowUserModel workOrderFlowUserModel;
    @Resource
    private WorkOrderProductService workOrderProductService;
    @Resource
    private MobileDetailService mobileDetailService;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private EsHelper esHelper;
    @Resource
    private WorkOrderCcModel workOrderCcModel;
    @Resource
    private PaasProcessTemplateModel paasProcessTemplateModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private UserTeamService userTeamService;
    @Resource
    @Lazy
    private RuleBusinessLogger ruleBusinessLogger;
    @Resource
    private FormDataValidateProductHelp formDataValidateProductHelp;
    @Resource
    private OpportunityService opportunityService;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private BusinessProductService businessProductService;
    @Resource
    private FormDataUpdateGetAnalysisDataHelp formDataUpdateGetAnalysisDataHelp;
    @Resource
    private UserHelp userHelp;
    @Resource
    private LinkProductRelyModel linkProductRelyModel;
    @Resource
    private RelativeProductHelp relativeProductHelp;
    @Resource
    private LogHelp logHelp;
    @Resource
    private LogHandleHelp logHandleHelp;
    @Resource
    private ContractModel contractModel;
    @Resource
    private WorkOrderValidateAnalyticalServiceImpl workOrderAnalyticalService;
    @Resource
    private WorkOrderHelp workOrderHelp;
    @Resource
    private TeamDataHelp teamDataHelp;
    @Resource
    private UserTeamHelp userTeamHelp;
    @Resource
    private DynamicStrategyFactory dynamicStrategyFactory;
    @Resource
    private TransactionHelp transactionHelp;

    @Override
    public void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException {
        workOrderAnalyticalService.beforeSave(validateDataDTO);
    }





    @Override
    public void  afterSave(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        //获取data
        WorkOrderEntity workOrderEntity = saasFormSaveDTO.getNewWorkOrderEntity();
        String creatorId = workOrderEntity.getCreatorId();
        JSONObject data = saasFormSaveDTO.getNewData();
        Long templateId = workOrderEntity.getTemplateId();
        String corpid = saasFormSaveDTO.getCorpid();
        Long workOrderId = workOrderEntity.getId();
        //产品保存
        if (saasFormSaveDTO.getIsNew() || saasFormSaveDTO.getSaasNeedRedundantAttrPoJo().getAttrCanSee(WorkOrderEnum.SPARE_PARTS.getAttr())) {
            JSONArray productJsonArray = data.getJSONArray(WorkOrderEnum.SPARE_PARTS.getAttr());
            saveProduct(productJsonArray, corpid, workOrderId,workOrderEntity.getFormId());
        }
        if (!Objects.equals(saasFormSaveDTO.getFromOuterLink(), 1)) {
            // 外链没有团队字段，所以外链保存是不需要处理团队字段的
            //负责团队保存
            PaasFormDataEntity newPaasFormDataEntity = new PaasFormDataEntity();
            BeanUtil.copyProperties(workOrderEntity, newPaasFormDataEntity);
            if(saasFormSaveDTO.getIsNew()){
                saasFormSaveDTO.getSaasNeedRedundantAttrPoJo().getTeamAfterVerifyDTO().getAddMainUserMap().clear();
            }
            teamDataHelp.saveUserTeam(saasFormSaveDTO.getSaasNeedRedundantAttrPoJo(), workOrderId, newPaasFormDataEntity, saasFormSaveDTO.getIsImport(), false);
        }

        //获取工单的模板，根据模板产生相应的工单流程
        WorkOrderTemplateEntity templateEntity = workOrderTemplateModel.getBykey(templateId, corpid);
        if (templateEntity == null) {
            throw new XbbException(WorkOrderErrorCodeEnum.API_ERROR_222011);
        }
        Integer expectedTime = 0;
        WorkOrderStageEntity workOrderStageEntity = null;
        //当前阶段id
        Long nowStageId = 0L;
        //阶段名称
        String stageName = "";
        boolean ifFree = Objects.equals(templateEntity.getIsFree(), 1);
        //产生相应的工单流程, 自由流程和指定流程的预计时间不同计算
        if (ifFree) {
            //自由流程
            expectedTime = templateEntity.getExpectedTime();
        } else {
            //指定流程
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("templateId", templateEntity.getId());
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("orderByStr", "sort");
            List<WorkOrderStageEntity> stageEntityList = workOrderStageModel.findEntitys(param);
            if (stageEntityList.isEmpty()) {
                throw new XbbException(WorkOrderErrorCodeEnum.API_ERROR_222025);
            }
            //取第一个阶段
            workOrderStageEntity = stageEntityList.get(0);
            nowStageId = workOrderStageEntity.getId();
            for (WorkOrderStageEntity entity : stageEntityList) {
                expectedTime += entity.getExpectedTime();
            }
            stageName = workOrderStageEntity.getName();
        }
        //存入阶段名称(阶段名称为空时不存)
        if (!Objects.equals(stageName, "")) {
            data.put(WorkOrderEnum.STAGE_NAME.getAttr(), stageName);
        }
        templateEntity.setExpectedTime(expectedTime);
        workOrderEntity.setStatus(WorkOrderStatusEnum.UNACCEPTED.getCode());
        workOrderEntity.setNowStageId(nowStageId);
        workOrderEntity.setExpectedTime(expectedTime);
        workOrderEntity.setActualTime(0);
        workOrderEntity.setStartTime(0L);
        workOrderEntity.setEndTime(0L);
        workOrderEntity.setCloseTime(0L);

        //获取工单流程设置, 新建第一个节点, 生成工单流程节点
        CreateNodeReturnPojo createNodeReturnPojo = workOrderBasicService.createNode(workOrderEntity,templateEntity,workOrderStageEntity);
        if (createNodeReturnPojo.getIsRob()) {
            workOrderEntity.setType(WorkOrderTypeEnum.ROB.getCode());
        }
        Integer nodeStatus = createNodeReturnPojo.getWorkOrderFlowNodeEntity().getStatus();
        data.put(WorkOrderEnum.NODE_STATUS.getAttr(), nodeStatus);
        //去除productList这个字段,array_1只存parentId
//        JSONObject jsonObject = data.getJSONObject(WorkOrderEnum.SPARE_PARTS.getAttr());
//        JSONArray productList = new JSONArray();
//        List<Long> pageProductIds = new ArrayList<>();
//        if (jsonObject != null) {
//            productList = jsonObject.getJSONArray(StringConstant.PRODUCT_LIST);
//        }
//        if (productList.size() > 0) {
//            for (int i = 0; i < productList.size(); i++) {
//                JSONObject product = productList.getJSONObject(i);
//                 页面传入的产品id
//                Long producId = product.getLong("id");
//                pageProductIds.add(producId);
//            }
//            data.put(WorkOrderEnum.SPARE_PARTS.getAttr(), pageProductIds);
//        } else {
//            data.put(WorkOrderEnum.SPARE_PARTS.getAttr(), new JSONArray());
//        }
        saasSaveHelp.formatSelectProduct4Save2(data, WorkOrderEnum.SPARE_PARTS.getAttr());
        workOrderEntity.setData(data);
        workOrderModel.save(workOrderEntity);
        workOrderFlowNodeModel.save(createNodeReturnPojo.getWorkOrderFlowNodeEntity());
        //新建节点的用户id
        String userId = createNodeReturnPojo.getUserId();
        workOrderFlowUserService.createNewMain(workOrderId, corpid, userId);

        //生成抄送人员数据
        workOrderCcService.save(workOrderId, corpid, JSONArray.parseArray(templateEntity.getCc()));

        UserEntity creator = userModel.getByKeyIngoreDel(creatorId, corpid);
        //消息推送
        if (userId == null ) {
            //抢单推送
            PushRefTypePojo.Options options = new PushRefTypePojo.Options(workOrderEntity.getAppId(), workOrderEntity.getMenuId(), workOrderEntity.getFormId(), workOrderEntity.getId(), SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.WORK_ORDER.getCode());
            MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, new ArrayList<>(createNodeReturnPojo.getPushIdList()), Collections.singletonList(workOrderId), 0, DateTimeUtil.getInt(), I18nMessageUtil.getMessage(WorkOrderPushConstant.WORK_ORDER_WAIT_ROB_TITLE), String.format(I18nMessageUtil.getMessage(WorkOrderPushConstant.PUSH_TO_ROB), workOrderEntity.getSerialNo(), workOrderStageEntity.getName()), null, options);
            baseProducer.sendMessage(PushTypeEnum.WORKORDER_PUSH, messageRabbitMqDTO);

        } else {
            List<String> pushUserIds;
            String pushMsg;
            UserEntity userEntity = userModel.getByKey(userId, corpid);
            if (Objects.equals(creatorId, userId)) {
                //创建人为第一阶段负责人
                pushUserIds = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.WORKORDER_NEW_EXECUTED.getCode(), PushTypeEnum.WORKORDER_NEW_EXECUTED.getSubCode(), userEntity, workOrderEntity);

                JSONObject dataObj = workOrderEntity.getData();
                String implementingTimeStr = "";
                if (Objects.nonNull(dataObj)) {
                    Long time = dataObj.getLong(WorkOrderEnum.IMPLEMENTATION_TIME.getAttr());
                    if (Objects.nonNull(time)) {
                        implementingTimeStr = DateTimeUtil.getString(time * 1000, DateTimeUtil.SDFYMDHM);
                    }
                }
                if (implementingTimeStr.isEmpty()) {
                    pushMsg = String.format(I18nMessageUtil.getMessage(WorkOrderPushConstant.PUSH_NEW_NO_TIME), userEntity.getName(), workOrderEntity.getSerialNo());
                } else {
                    pushMsg = String.format(I18nMessageUtil.getMessage(WorkOrderPushConstant.PUSH_NEW), userEntity.getName(), workOrderEntity.getSerialNo(), implementingTimeStr);
                }
                PushRefTypePojo.Options options = new PushRefTypePojo.Options(workOrderEntity.getAppId(), workOrderEntity.getMenuId(), workOrderEntity.getFormId(), workOrderEntity.getId(), SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.WORK_ORDER.getCode());

                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserIds, Collections.singletonList(workOrderId), 0, DateTimeUtil.getInt(), I18nMessageUtil.getMessage(WorkOrderPushConstant.WORKORDER_NEW_EXECUTED_TITLE), pushMsg, null, options);
                baseProducer.sendMessage(PushTypeEnum.WORKORDER_NEW_EXECUTED, messageRabbitMqDTO);

            } else {
                //创建人不为第一阶段负责人
                UserVO loginUser = saasFormSaveDTO.getLoginUser();
                if (!Objects.equals(saasFormSaveDTO.getFromOuterLink(),1)){
                    if (Objects.equals(userId, loginUser.getUserId())) {
                        //操作人和指定的人相同
                        pushMsg = String.format(I18nMessageUtil.getMessage(WorkOrderPushConstant.PUSH_NEW_TODO), creator.getName(), workOrderEntity.getSerialNo());
                        pushUserIds = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.WORKORDER_NEW_EXECUTOR.getCode(), PushTypeEnum.WORKORDER_NEW_EXECUTOR.getSubCode(), userEntity, workOrderEntity);
                        PushRefTypePojo.Options options = new PushRefTypePojo.Options(workOrderEntity.getAppId(), workOrderEntity.getMenuId(), workOrderEntity.getFormId(), workOrderEntity.getId(), SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.WORK_ORDER.getCode());

                        MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserIds, Collections.singletonList(workOrderId), 0, DateTimeUtil.getInt(), I18nMessageUtil.getMessage(WorkOrderPushConstant.WORKORDER_NEW_EXECUTOR_TITLE), pushMsg, null, options);
                        baseProducer.sendMessage(PushTypeEnum.WORKORDER_NEW_EXECUTOR, messageRabbitMqDTO);
                    } else {
                        //操作人和指定的人不同
                        pushMsg = String.format(I18nMessageUtil.getMessage(WorkOrderPushConstant.PUSH_NEW_TODO), creator.getName(), workOrderEntity.getSerialNo());
                        pushUserIds = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.WORKORDER_NEW_EXECUTOR.getCode(), PushTypeEnum.WORKORDER_NEW_EXECUTOR.getSubCode(), loginUser, workOrderEntity);
                        PushRefTypePojo.Options options = new PushRefTypePojo.Options(workOrderEntity.getAppId(), workOrderEntity.getMenuId(), workOrderEntity.getFormId(), workOrderEntity.getId(), SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.WORK_ORDER.getCode());

                        MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserIds, Collections.singletonList(workOrderId), 0, DateTimeUtil.getInt(), I18nMessageUtil.getMessage(WorkOrderPushConstant.WORKORDER_NEW_EXECUTOR_TITLE), pushMsg, null, options);
                        baseProducer.sendMessage(PushTypeEnum.WORKORDER_NEW_EXECUTOR, messageRabbitMqDTO);
                    }
                }


            }

        }

        if (saasFormSaveDTO.getIsNew()) {
            // 新建工单动态
            if (!Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(), saasFormSaveDTO.getDistributorMark())) {
                DynamicStrategy dynamicStrategy = dynamicStrategyFactory.getDynamicStrategy(ProjectLogEnum.WORK_ORDER_CREATE.getSubType());
                transactionHelp.afterCommitOrCommitNow(p->{
                    dynamicStrategy.save(DynamicSaveDTO.initDynamicSaveDTO(workOrderId, workOrderEntity.getFormId(), saasFormSaveDTO, creator, null));
                });
            }
        }
    }

    @Override
    public void formatAddExplain(FormatExplainDTO formatExplainDTO) throws XbbException {
        List<FieldAttrEntity> explainList = formatExplainDTO.getExplainList();
        String corpid = formatExplainDTO.getCorpid();
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            String attr = fieldAttrEntity.getAttr();
            if (Objects.equals(attr, WorkOrderEnum.SPARE_PARTS.getAttr())) {
                explainHelp.formatSelectProductExplains(fieldAttrEntity, XbbRefTypeEnum.WORK_ORDER, corpid, OperatePageEnum.NEW.getCode(), false);
                fieldAttrEntity.setSupportScanning(1);
            }
        }
    }





    @Override
    public WorkOrderChangeFlowItemVO getChangeFlowItem(ChangeWorkflowItemDTO changeWorkflowItemDTO) throws XbbException {
        Long workOrderId = changeWorkflowItemDTO.getWorkOrderId();
        String corpid = changeWorkflowItemDTO.getCorpid();
        List<FieldAttrEntity> headList = new ArrayList<>();
        WorkOrderStageOperationEnum workOrderStageOperationEnum = WorkOrderStageOperationEnum.getByAlias(changeWorkflowItemDTO.getOperate());
        switch (workOrderStageOperationEnum){
            case COMPLETE:
                headList = workOrderBasicService.completeItem(workOrderId,corpid);
                break;
            case ROLLBACK:
                headList = workOrderBasicService.rollbackItem();
                break;
            case CLOSE:
                headList = workOrderBasicService.closeItem();
                break;
            case TRANSFER:
                headList = workOrderBasicService.transferItem(workOrderId,corpid);
                break;
            case RESTART:
                headList = workOrderBasicService.restartItem(workOrderId,corpid);
                break;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        WorkOrderChangeFlowItemVO workOrderChangeFlowItemVO = new WorkOrderChangeFlowItemVO();
        workOrderChangeFlowItemVO.setHeadList(headList);
        return workOrderChangeFlowItemVO;
    }

    @Override
    public BusinessProductListVO getWorkOrderProductList(BusinessProductListDTO businessProductListDTO, Object object) throws XbbException {
        BusinessProductListVO businessProductListVO = new BusinessProductListVO();
        try {
            String corpid = businessProductListDTO.getCorpid();
            String userId = businessProductListDTO.getUserId();
            Long workOrderId = businessProductListDTO.getDataId();
            UserEntity userEntity = userModel.getByKey(userId, corpid);
            boolean detailGet = businessProductListDTO.getDetailGet();
            Integer businessType = businessProductListDTO.getBusinessType();
            XbbRefTypeEnum xbbRefTypeEnum;

            JSONObject productFinalObj = new JSONObject();
            SaasAnalysisDataDTO saasAnalysisDataDTO = new SaasAnalysisDataDTO();
            BeanUtil.copyProperties(businessProductListDTO, saasAnalysisDataDTO, true);
            //工单关联的产品
            List<WorkOrderProductEntity> workProductList = new ArrayList<>();
            //关联产品信息
            List<ProductStockInfoEntity> productStockInfoList = new ArrayList<>();
            List<Long> productIds = new ArrayList<>();
            productIds.add(-1L);
            WorkOrderEntity workOrderEntity = new WorkOrderEntity();
            Map<String, Object> paramMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            paramMap.put(ParameterConstant.CORPID, corpid);
            paramMap.put("workOrderId", workOrderId);
            paramMap.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            paramMap.put(ParameterConstant.PAGE,  businessProductListDTO.getPage());
            PageHelper pageHelper = PageHelperUtil.getPageHelper(paramMap, workOrderProductModel, businessProductListDTO.getPageSize());
            if (businessProductListDTO.getForProcess() && object != null) {
                //审批用

            } else {
                workOrderEntity = workOrderModel.getByKey(workOrderId, corpid);
                workProductList = (List<WorkOrderProductEntity>) PageHelperUtil.getEntityList(paramMap, pageHelper, workOrderProductModel);
            }
            if (workOrderEntity == null || Objects.equals(workOrderEntity.getDel(), DelEnum.DELETE.getDel())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
            }
            if (workProductList == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }

            JSONObject data = workOrderEntity.getData();
            //formatProduct4Show(data, saasAnalysisDataDTO);
            //productFinalObj = data.getJSONObject(WorkOrderEnum.SPARE_PARTS.getAttr());
            // 用于存放当前启用的产品模板解释的map
            Map<String, FieldAttrEntity> nowProductExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<String, Object> modelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            modelMap.put("corpid", corpid);
            modelMap.put("del", 0);
            modelMap.put("saasMark", 1);
            if (detailGet) {
                modelMap.put("businessType", XbbRefTypeEnum.PRODUCT.getCode());
            } else {
                modelMap.put("businessType", XbbRefTypeEnum.OUTSTOCK.getCode());
            }
            List<PaasFormExplainEntity> formExplainList = paasFormExplainModel.list(modelMap);
            if (!formExplainList.isEmpty()) {
                PaasFormExplainEntity paasFormExplainEntity = formExplainList.get(0);
                List<FieldAttrEntity> nowProductExplainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                for (FieldAttrEntity entity : nowProductExplainList) {
                    nowProductExplainMap.put(entity.getSaasAttr(), entity);
                }
            }
            if (detailGet) {
                xbbRefTypeEnum = XbbRefTypeEnum.WORK_ORDER;
                //若是不可见的情况产品详情也不予回显
                Long formId = workOrderEntity.getFormId();
                //获取解释
                WorkOrderExplainEntity workOrderExplainEntity = workOrderExplainModel.getByFormId(formId, corpid);
                if (workOrderExplainEntity == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                List<FieldAttrEntity> explainList = JSONArray.parseArray(workOrderExplainEntity.getExplains(), FieldAttrEntity.class);
                Map<String, FieldAttrEntity> explainMap = new LinkedHashMap<>(explainList.size());
                // 将字段放入字段容器
                for (FieldAttrEntity fieldAttrEntity : explainList) {
                    explainMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
                }
                //协同团队
                Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                userTeamService.getUserIdMap(Collections.singletonList(workOrderId), corpid, XbbRefTypeEnum.WORK_ORDER.getCode(), false, mainUserMap, coUserMap);
                // 当前数据的创建人、负责人、协同人、当前操作人
                HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
                handlerExplainDTO.setOwnerId(mainUserMap.get(workOrderId));
                handlerExplainDTO.setCoUserId(coUserMap.get(workOrderId));
                handlerExplainDTO.setCreatorId(workOrderEntity.getCreatorId());
                handlerExplainDTO.setUserId(userId);
                handlerExplainDTO.setLoginUser(businessProductListDTO.getLoginUser());
                //实施备件不可见时不予回显
                if (!commonHelp.attrCanSee(WorkOrderEnum.SPARE_PARTS.getAttr(), explainMap, handlerExplainDTO)) {
                    JSONArray jsonArray = new JSONArray();
                    productFinalObj.put(StringConstant.PRODUCT_LIST, jsonArray);
                    pageHelper.setRowsCount(BasicConstant.ZERO);
                } else {
                    detailProduct(data, saasAnalysisDataDTO, workProductList);
                    productFinalObj = data.getJSONObject(WorkOrderEnum.SPARE_PARTS.getAttr());
                }
            } else {
                xbbRefTypeEnum = XbbRefTypeEnum.OUTSTOCK;
                outstockProduct(data, saasAnalysisDataDTO);
                productFinalObj = data.getJSONObject(WorkOrderEnum.SPARE_PARTS.getAttr());
            }
            Integer targetCode = businessProductListDTO.getBusinessType();
            // 获取关联产品需要展示的字段
            BusinessProductEnum businessProductEnum = BusinessProductEnum.getByCodeAndTargetCode(xbbRefTypeEnum.getCode(), targetCode);
            List<FieldAttrEntity> relativeProductExplains = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (businessProductEnum != BusinessProductEnum.UNKNOW) {
                List<RelativeProductEnum> businessProductEnumList = businessProductEnum.getList();
                relativeProductExplains = explainHelp.getRelativeProductExplainList(businessProductEnumList,nowProductExplainMap, null ,
                        xbbRefTypeEnum, WorkOrderEnum.SPARE_PARTS.getAttr());
            }
            productFinalObj.put(BusinessConstant.EXPLAINS, relativeProductExplains);
            productFinalObj.put(StringConstant.REDUNDANT_FIELD_ATTR_BEGIN_FLAG, WorkOrderEnum.SPARE_PARTS.getAttr());
            businessProductListVO.setProduct(productFinalObj);
            if (detailGet) {
                if (productFinalObj.getJSONArray(StringConstant.PRODUCT_LIST).size() != 0 && (Objects.isNull(workOrderEntity.getAllOutbound()) || Objects.equals(workOrderEntity.getAllOutbound(), 0)) && businessProductListDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.OUTSTOCK_ADD.getAlias())) {
                    ButtonPojo buttonPojo = new ButtonPojo();
                    buttonPojo.setAttr("exWarehouse");
                    buttonPojo.setValue(I18nMessageUtil.getMessage(I18nStringConstant.ONE_CLICK_DELIVERY));
                    buttonPojo.setLinkBusinessType(XbbRefTypeEnum.OUTSTOCK.getCode());
                    List<ButtonPojo> topRightButton = new ArrayList<>();
                    topRightButton.add(buttonPojo);
                    businessProductListVO.setTopRightButton(topRightButton);
                }
            }
            businessProductListVO.setPageHelper(pageHelper);
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("workOrderServiceImpl.getWorkOrderProductList 出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return businessProductListVO;
    }

    @Override
    public List<WorkOrderProductEntity> saveProduct(JSONArray productArray, String corpid, Long workOrderId, Long formId) throws XbbException {
        productArray = Objects.isNull(productArray) ? new JSONArray() : productArray;
        Map<Long, WorkOrderProductEntity> originProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long,Double> outstockNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<WorkOrderProductEntity> dbList = workOrderProductModel.getProductsByWorkOrderId(workOrderId, corpid, Arrays.asList(DelEnum.NORMAL.getDel(), DelEnum.APPROVE_FAILED.getDel()));
        for (WorkOrderProductEntity workOrderProductEntity : dbList) {
            originProductMap.put(workOrderProductEntity.getId(),workOrderProductEntity);

            Double outstockNum = outstockNumMap.getOrDefault(workOrderProductEntity.getProductId(),0D);
            outstockNumMap.put(workOrderProductEntity.getProductId(),Arith.add(outstockNum,workOrderProductEntity.getOutstockNum()));
        }
        List<WorkOrderProductEntity> productAddList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //编辑产品
        List<WorkOrderProductEntity> productUpdateList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, PaasFormDataEntityExt> productMap = formDataValidateProductHelp.product2saveMap(corpid,productArray);
        Integer sort = 0;
        for (int i = 0; i < productArray.size(); i++) {
            JSONObject jsonObject = productArray.getJSONObject(i);
            Long pageProductId = jsonObject.getLong(SelectProductEnum.PRODUCT.getAttr());
            Long businessProductId = jsonObject.getLong(BusinessConstant.PRODUCT_SUB_ID);
            Double productNum = jsonObject.getDouble(WorkOrderProductEnum.NUM.getAttr());
            String memo = jsonObject.getString(WorkOrderProductEnum.MEMO.getAttr());
            boolean addProductFlag = formDataValidateProductHelp.addProductFlag(businessProductId);
            WorkOrderProductEntity workOrderProductEntity;
            if (!productMap.containsKey(pageProductId)) {
                continue;
            }
            JSONObject productData = productMap.get(pageProductId).getData();
            if (addProductFlag) {
                //新增产品
                workOrderProductEntity = new WorkOrderProductEntity();
                productAddList.add(workOrderProductEntity);
            } else if (originProductMap.containsKey(businessProductId)) {
                //编辑产品
                workOrderProductEntity = originProductMap.get(businessProductId);
                if (Objects.equals(DelEnum.APPROVE_FAILED.getDel(), workOrderProductEntity.getDel())) {
                    workOrderProductEntity.setDel(DelEnum.NORMAL.getDel());
                }
                productUpdateList.add(workOrderProductEntity);
                //只剩删除的产品
                originProductMap.remove(businessProductId);
                productData.put(SelectProductEnum.PRICE.getAttr(),workOrderProductEntity.getProductPrice());
            } else {
                //删除产品
                continue;
            }
            workOrderProductEntity.setCorpid(corpid);
            workOrderProductEntity.setFormId(formId);
            workOrderProductEntity.setWorkOrderId(workOrderId);
            workOrderProductEntity.setParentId(productData.getLong(ProductEnum.PARENT_ID.getAttr()));
            workOrderProductEntity.setProductId(pageProductId);
            workOrderProductEntity.setProductName(productData.getString(ProductEnum.NAME.getAttr()));
            String productNo = productData.getString(ProductEnum.PRODUCT_NO.getAttr());
            productNo = Objects.isNull(productNo) ? "" : productNo;
            workOrderProductEntity.setProductNo(productNo);
            workOrderProductEntity.setProductPrice(productData.getDouble(ProductEnum.PRICE.getAttr()));
            String unit = productData.getString(ProductEnum.UNIT.getAttr());
            unit = Objects.isNull(unit) ? "" : unit;
//            workOrderProductEntity.setProductUnit(unit);
            workOrderProductEntity.setSort(sort);
            workOrderProductEntity.setSpecification(productData.getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr()));
            workOrderProductEntity.setProductNum(productNum);
            workOrderProductEntity.setDel(DelEnum.NORMAL.getDel());
            workOrderProductEntity.setMemo(jsonObject.getString(SelectProductEnum.MEMO.getAttr()));
            Integer enableMultiUnit = productData.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getAttr());
            if (Objects.equals(enableMultiUnit, 1)) {
                formDataValidateProductHelp.setBusinessUnit(jsonObject, workOrderProductEntity);
                workOrderProductEntity.setProductUnit(jsonObject.getString(SelectProductEnum.UNIT.getAttr()));
            } else {
                workOrderProductEntity.setProductUnit(productData.getString(ProductEnum.UNIT.getAttr()));
                jsonObject.put(WorkOrderProductEnum.UNIT.getAttr(),unit);
            }
            if (Objects.isNull(workOrderProductEntity.getProductUnit())) {
                workOrderProductEntity.setProductUnit("");
            }
            workOrderProductEntity.setData(jsonObject);
            //老数据维护一下出库数
            if (Objects.isNull(workOrderProductEntity.getRefProductId())){
                if (outstockNumMap.containsKey(workOrderProductEntity.getProductId())){
                    Double amendNum = outstockNumMap.get(workOrderProductEntity.getProductId());
                    Double outstockNum = workOrderProductEntity.getProductNum() < amendNum ? workOrderProductEntity.getProductNum() : amendNum;
                    workOrderProductEntity.setOutstockNum(outstockNum);
                    amendNum = Arith.sub(amendNum,outstockNum);
                    if (amendNum > 0){
                        outstockNumMap.put(workOrderProductEntity.getProductId(),amendNum);
                    }else {
                        outstockNumMap.remove(workOrderProductEntity.getProductId());
                    }
                }else {
                    workOrderProductEntity.setOutstockNum(0D);
                }
            }
            sort ++;
//            workOrderProductModel.save(workOrderProductEntity);
//            newProducts.add(workOrderProductEntity);
        }

        workOrderProductModel.insertBatch(productAddList);
        workOrderProductModel.updateMulti(productUpdateList, corpid);
        List<Long> delList = new ArrayList<>();
        for (Map.Entry<Long, WorkOrderProductEntity> entry : originProductMap.entrySet()) {
            delList.add(entry.getKey());
        }
        workOrderProductModel.deleteBatch(delList, corpid,DelEnum.DELETE.getDel());

        return new ArrayList<>();
    }


    @Override
    public void formatProduct4Show(JSONObject dataList, SaasAnalysisDataDTO saasAnalysisDataDTO) throws XbbException {
        if (dataList == null || saasAnalysisDataDTO == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
        }
        String corpid = saasAnalysisDataDTO.getCorpid();
        Long workOrderId = saasAnalysisDataDTO.getDataId();
        double totalProductMoney = 0D;
        Double productPrice = 0D;
        Double productNum = 0D;
        String totalMoney = "";
        List<WorkOrderProductEntity> workOrderProductList = new ArrayList<>();
        if (saasAnalysisDataDTO.getForProcess()) {
            JSONArray productArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(FastJsonHelper.getJsonObjectOrDefaultFromFormData(dataList, WorkOrderEnum.SPARE_PARTS.getAttr(), new JSONObject()), StringConstant.PRODUCT_LIST, new JSONArray());
            Map<Long, ProductEntityExt> productMap = productModel.getProductMap(corpid, productArray);
            workOrderModel.getProductList(corpid, workOrderProductList, productArray, productMap);
        } else {
            workOrderProductList = workOrderProductModel.getProductsByWorkOrderId(workOrderId, corpid);
        }
        if (workOrderProductList == null || workOrderProductList.size() == 0) {
            JSONObject productFinalObj = new JSONObject();
            productFinalObj.put(StringConstant.PRODUCT_LIST, new JSONArray());
            dataList.put(WorkOrderEnum.SPARE_PARTS.getAttr(), productFinalObj);
            return;
        }
        List<Long> productIds = new ArrayList<>(workOrderProductList.size());
        for (WorkOrderProductEntity entity : workOrderProductList) {
            productIds.add(entity.getProductId());
        }
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("idIn", productIds);
        List<ProductEntityExt> productEntityExtList = productModel.findEntitys(param);
        if (productEntityExtList == null || productEntityExtList.size() == 0) {
            JSONObject productFinalObj = new JSONObject();
            productFinalObj.put(StringConstant.PRODUCT_LIST, new JSONArray());
            dataList.put(WorkOrderEnum.SPARE_PARTS.getAttr(), productFinalObj);
            return ;
        }
        Map<Long, ProductEntityExt> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (ProductEntityExt entityExt : productEntityExtList) {
            map.put(entityExt.getId(), entityExt);
        }
        // 获取关联产品需要展示的字段
        BusinessProductEnum businessProductEnum = BusinessProductEnum.getByCode(XbbRefTypeEnum.WORK_ORDER.getCode());

        Map<String, FieldAttrEntity> nowProductExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.clear();
        param.put("corpid", corpid);
        param.put("del", 0);
        param.put("saasMark", 1);
        param.put("businessType", XbbRefTypeEnum.PRODUCT.getCode());
        List<PaasFormExplainEntity> formExplainList = paasFormExplainModel.list(param);
        if (!formExplainList.isEmpty()) {
            PaasFormExplainEntity paasFormExplainEntity = formExplainList.get(0);
            List<FieldAttrEntity> nowProductExplainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            for (FieldAttrEntity entity : nowProductExplainList) {
                nowProductExplainMap.put(entity.getSaasAttr(), entity);
            }
        }

        JSONObject productFinalObj = new JSONObject();
        JSONObject othersObj = new JSONObject();
        JSONArray productArray = new JSONArray();
        Map<Integer, JSONObject> productMap = new TreeMap<>();
        if (businessProductEnum != BusinessProductEnum.UNKNOW) {
            List<RelativeProductEnum> businessProductEnumList = businessProductEnum.getList();
            for (WorkOrderProductEntity entity : workOrderProductList) {
                JSONArray attrArray = new JSONArray();
                JSONObject productObj = new JSONObject();
                Long productId = entity.getProductId();
                if (map.containsKey(productId)) {
                    JSONObject productData = map.get(productId).getData();

                    for (RelativeProductEnum productEnum : businessProductEnumList) {
                        String saasAttr = productEnum.getSaasAttr();
                        FieldAttrEntity fieldAttrEntity = null;
                        if (nowProductExplainMap.containsKey(saasAttr)) {
                            fieldAttrEntity = nowProductExplainMap.get(saasAttr);
                        }
                        switch (productEnum) {
                            case NAME:
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(NAME, entity.getProductName(), fieldAttrEntity));
                                break;
                            case PRODUCT_NO:
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(PRODUCT_NO, entity.getProductNo(), fieldAttrEntity));
                                break;
                            case SPECIFICATION:
                                // 格式化规格
                                String specification = specificationModel.joinSpecification(entity.getSpecification());
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(SPECIFICATION, specification, fieldAttrEntity));
                                break;
                            case PRODUCT_PRICE:
                                productPrice = productData.getDouble(ProductEnum.PRICE.getAttr());
                                productPrice = productPrice == null ? 0 : productPrice;
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(PRODUCT_PRICE, productPrice, fieldAttrEntity));
                                break;
                            case NUM:
                                productNum = entity.getProductNum();
                                productNum = productNum == null ? 0 : productNum;
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(NUM, productNum, fieldAttrEntity));
                                break;
                            case UNIT:
                                String productUnit = entity.getProductUnit();
                                String unitStr = productModel.getProductUnitTextByValue(productUnit, fieldAttrEntity);
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(UNIT, unitStr, fieldAttrEntity));
                                break;
                            default:
                        }
                        productObj.put("result", attrArray);
                        productObj.put(StringConstant.SAAS_LINK_BUSINESS_ID, entity.getProductId());
                        productObj.put("parentId",entity.getParentId());
                        productObj.put(StringConstant.BUSINESS_PRODUCT_ID, entity.getId());
                    }
                    Double subTotal = productPrice * productNum;
                    // 小计
                    totalProductMoney = Arith.add(totalProductMoney, subTotal);
                    totalMoney = attrDecimalPrecisionHelper.formatMoneyPrecision(totalProductMoney, nowProductExplainMap, null);
                }
                productMap.put(entity.getSort(), productObj);
            }
            productArray.addAll(productMap.values());
            productFinalObj.put(StringConstant.PRODUCT_LIST, productArray);
            othersObj.put(BusinessConstant.TOTAL_PRODUCT_MONEY, totalMoney);
            productFinalObj.put(BusinessConstant.OTHERS, othersObj);

        }


        dataList.put(WorkOrderEnum.SPARE_PARTS.getAttr(), productFinalObj);
    }


    private void detailProduct(JSONObject dataList, SaasAnalysisDataDTO saasAnalysisDataDTO, List<WorkOrderProductEntity> workOrderProductList) throws XbbException {
        if (dataList == null || saasAnalysisDataDTO == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
        }
        String corpid = saasAnalysisDataDTO.getCorpid();
        Long workOrderId = saasAnalysisDataDTO.getDataId();
        double totalProductMoney = 0D;
        Double productPrice = 0D;
        Double productNum = 0D;
        String totalMoney = "";
        /*List<WorkOrderProductEntity> workOrderProductList = workOrderProductModel.getProductsByWorkOrderId(workOrderId, corpid);*/
        if (workOrderProductList == null || workOrderProductList.size() == 0) {
            JSONObject result = new JSONObject();
            result.put(StringConstant.PRODUCT_LIST, new JSONArray());
            dataList.put(WorkOrderEnum.SPARE_PARTS.getAttr(), result);
            return;
        }
        Set<Long> productIds = new HashSet<>(workOrderProductList.size());
        for (WorkOrderProductEntity entity : workOrderProductList) {
            productIds.add(entity.getProductId());
        }
//        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//        param.put("corpid", corpid);
//        param.put("del", DelEnum.NORMAL.getDel());
//        param.put("idIn", productIds);
//        List<ProductEntityExt> productEntityExtList = productModel.findEntitys(param);
//        if (productEntityExtList == null || productEntityExtList.size() == 0) {
//            return;
//        }
//        Map<Long, ProductEntityExt> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//        for (ProductEntityExt entityExt : productEntityExtList) {
//            map.put(entityExt.getId(), entityExt);
//        }
        Map<Long, PaasFormDataEntityExt> map = productService.getProductMapByIdIn(productIds,corpid,DelEnum.NORMAL);
        Map<Long, PaasFormDataEntityExt> map1 = productService.getProductMapByIdIn(productIds,corpid,DelEnum.DELETE);
        map.putAll(map1);
        // 获取关联产品需要展示的字段
        BusinessProductEnum businessProductEnum = BusinessProductEnum.getByCode(XbbRefTypeEnum.WORK_ORDER.getCode());

        Map<String, FieldAttrEntity> nowProductExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", 0);
        param.put("saasMark", 1);
        param.put("businessType", XbbRefTypeEnum.PRODUCT.getCode());
        List<PaasFormExplainEntity> formExplainList = paasFormExplainModel.list(param);
        if (!formExplainList.isEmpty()) {
            PaasFormExplainEntity paasFormExplainEntity = formExplainList.get(0);
            List<FieldAttrEntity> nowProductExplainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            for (FieldAttrEntity entity : nowProductExplainList) {
                nowProductExplainMap.put(entity.getSaasAttr(), entity);
            }
        }

        JSONObject productFinalObj = new JSONObject();
        JSONObject othersObj = new JSONObject();
        JSONArray productArray = new JSONArray();
        Map<Integer, JSONObject> productMap = new TreeMap<>();
        if (businessProductEnum != BusinessProductEnum.UNKNOW) {
            List<RelativeProductEnum> businessProductEnumList = businessProductEnum.getList();
            for (WorkOrderProductEntity entity : workOrderProductList) {
                JSONArray attrArray = new JSONArray();
                JSONObject productObj = new JSONObject();
                Long productId = entity.getProductId();
                if (map.containsKey(productId)) {
                    JSONObject productData = map.get(productId).getData();

                    for (RelativeProductEnum productEnum : businessProductEnumList) {
                        String saasAttr = productEnum.getSaasAttr();
                        FieldAttrEntity fieldAttrEntity = null;
                        if (nowProductExplainMap.containsKey(saasAttr)) {
                            fieldAttrEntity = nowProductExplainMap.get(saasAttr);
                        }
                        switch (productEnum) {
                            case NAME:
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(NAME, entity.getProductName(), fieldAttrEntity));
                                break;
                            case PRODUCT_NO:
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(PRODUCT_NO, entity.getProductNo(), fieldAttrEntity));
                                break;
                            case SPECIFICATION:
                                // 格式化规格
                                String specification = specificationModel.joinSpecification(entity.getSpecification());
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(SPECIFICATION, specification, fieldAttrEntity));
                                break;
                            case PRODUCT_PRICE:
                                productPrice = productData.getDouble(ProductEnum.PRICE.getAttr());
                                productPrice = productPrice == null ? 0 : productPrice;
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(PRODUCT_PRICE, productPrice, fieldAttrEntity));
                                break;
                            case NUM:
                                if(Objects.isNull(fieldAttrEntity)) {
                                    fieldAttrEntity = new FieldAttrEntity();
                                }
                                FieldAttrEntity stockAttrEntity = nowProductExplainMap.get(ProductEnum.STOCK.getSaasAttr());
                                if(Objects.nonNull(stockAttrEntity)) {
                                    fieldAttrEntity.setAccuracy(stockAttrEntity.getAccuracy());
                                }
                                productNum = entity.getProductNum();
                                productNum = productNum == null ? 0 : productNum;
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(NUM, productNum, fieldAttrEntity));
                                break;
                            case UNIT:
                                String productUnit = entity.getProductUnit();
                                String unitStr = productModel.getProductUnitTextByValue(productUnit, fieldAttrEntity);
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(UNIT, unitStr, fieldAttrEntity));
                                break;
                            default:
                        }
                        productObj.put("result", attrArray);
                        productObj.put(StringConstant.SAAS_LINK_BUSINESS_ID, entity.getProductId());
                        productObj.put(StringConstant.BUSINESS_PRODUCT_ID, entity.getId());
                        productObj.put("parentId", entity.getParentId());
                    }
                    Double subTotal = productPrice * productNum;
                    // 小计
                    totalProductMoney = Arith.add(totalProductMoney, subTotal);
                    totalMoney = attrDecimalPrecisionHelper.formatMoneyPrecision(totalProductMoney, nowProductExplainMap, ProductEnum.PRICE.getSaasAttr());
                }
                productMap.put(entity.getSort(), productObj);
            }
            productArray.addAll(productMap.values());
            productFinalObj.put(StringConstant.PRODUCT_LIST, productArray);
            othersObj.put(BusinessConstant.TOTAL_PRODUCT_MONEY, totalMoney);
            productFinalObj.put(BusinessConstant.OTHERS, othersObj);

        }
        dataList.put(WorkOrderEnum.SPARE_PARTS.getAttr(), productFinalObj);
    }

    public void outstockProduct(JSONObject dataList, SaasAnalysisDataDTO saasAnalysisDataDTO) throws XbbException {
        if (dataList == null || saasAnalysisDataDTO == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
        }
        String corpid = saasAnalysisDataDTO.getCorpid();
        Long workOrderId = saasAnalysisDataDTO.getDataId();
        Double productNum = 0D;
        List<WorkOrderProductEntity> workOrderProductList = new ArrayList<>();
        workOrderProductList = workOrderProductService.getSurplusProduct(corpid, workOrderId, null, null);
        if (workOrderProductList == null || workOrderProductList.size() == 0) {
            JSONObject result = new JSONObject();
            result.put(StringConstant.PRODUCT_LIST, new JSONArray());
            dataList.put(WorkOrderEnum.SPARE_PARTS.getAttr(), result);
            return;
        }
        Set<Long> productIds = new HashSet<>(workOrderProductList.size());
        for (WorkOrderProductEntity entity : workOrderProductList) {
            productIds.add(entity.getProductId());
        }
//        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//        param.put("corpid", corpid);
//        param.put("del", DelEnum.NORMAL.getDel());
//        param.put("idIn", productIds);
//        List<ProductEntityExt> productEntityExtList = productModel.findEntitys(param);
//        if (productEntityExtList == null || productEntityExtList.size() == 0) {
//            return;
//        }
        Map<Long, PaasFormDataEntityExt> map = productService.getProductMapByIdIn(productIds,corpid,DelEnum.NORMAL);
//        for (ProductEntityExt entityExt : productEntityExtList) {
//            map.put(entityExt.getId(), entityExt);
//        }
        // 获取关联产品需要展示的字段
        BusinessProductEnum businessProductEnum = BusinessProductEnum.getByCode(XbbRefTypeEnum.OUTSTOCK.getCode());

        Map<String, FieldAttrEntity> nowProductExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", 0);
        param.put("saasMark", 1);
        param.put("businessType", XbbRefTypeEnum.PRODUCT.getCode());
        List<PaasFormExplainEntity> formExplainList = paasFormExplainModel.list(param);
        if (!formExplainList.isEmpty()) {
            PaasFormExplainEntity paasFormExplainEntity = formExplainList.get(0);
            List<FieldAttrEntity> nowProductExplainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
            for (FieldAttrEntity entity : nowProductExplainList) {
                nowProductExplainMap.put(entity.getSaasAttr(), entity);
            }
        }

        JSONObject productFinalObj = new JSONObject();
        JSONArray productArray = new JSONArray();
        Map<Integer, JSONObject> productMap = new TreeMap<>();
        if (businessProductEnum != BusinessProductEnum.UNKNOW) {
            List<RelativeProductEnum> businessProductEnumList = businessProductEnum.getList();
            for (WorkOrderProductEntity entity : workOrderProductList) {
                JSONArray attrArray = new JSONArray();
                JSONObject productObj = new JSONObject();
                Long productId = entity.getProductId();
                if (map.containsKey(productId)) {
                    JSONObject productData = map.get(productId).getData();

                    for (RelativeProductEnum productEnum : businessProductEnumList) {
                        String saasAttr = productEnum.getSaasAttr();
                        FieldAttrEntity fieldAttrEntity = null;
                        if (nowProductExplainMap.containsKey(saasAttr)) {
                            fieldAttrEntity = nowProductExplainMap.get(saasAttr);
                        }
//                        ProductEntityExt productEntityExt = productModel.getByKey(productId, corpid);
                        PaasFormDataEntityExt productEntityExt = map.get(productId);
//                        param.clear();
//                        param.put("corpid", corpid);
//                        param.put("del", 0);
//                        param.put("productId", productId);
//                        List<ProductWarehouseEntity> list = productWarehouseModel.findEntitys(param);
//                        if (list == null) {
//                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
//                        }
                        if (productEntityExt == null) {
                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100028);
                        }
                        JSONObject data = productEntityExt.getData();
                        switch (productEnum) {
                            case NAME:
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(NAME, entity.getProductName(), fieldAttrEntity));
                                break;
                            case PRODUCT_NO:
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(PRODUCT_NO, entity.getProductNo(), fieldAttrEntity));
                                break;
                            case BARCODE:
                                String barcode = data.getString(RelativeProductEnum.BARCODE.getAttr());
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(BARCODE, barcode, fieldAttrEntity));
                                break;
                            case WAREHOUSE:
                                ProductWarehouseMapDTO productWarehouseMapDTO = new ProductWarehouseMapDTO();
                                BeanUtil.copyProperties(saasAnalysisDataDTO, productWarehouseMapDTO);
                                productWarehouseMapDTO.setAllWarehouse(0);
                                productWarehouseMapDTO.setProductId(productId);
                                ProductWarehouseMapVO productWarehouseMapVO = warehouseService.getSelectProductWarehouses(productWarehouseMapDTO);
                                if (Objects.isNull(productWarehouseMapVO)) {
                                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                                }
                                Map<String, JSONArray> warehouseMap = productWarehouseMapVO.getProductWarehouseMap();
                                JSONArray warehouseArray = warehouseMap.get("userWarehouseArray");

                                JSONObject warehouseResultObj = saasUpdateHelp.formatSelectProduct4Show(WAREHOUSE, new JSONObject(), fieldAttrEntity);
                                if (warehouseResultObj != null) {
                                    warehouseResultObj.put("attrName", I18nMessageUtil.getMessage(StringConstant.OUT_WAREHOUSE));
                                    warehouseResultObj.put("warehouseArray", warehouseArray);
                                    attrArray.add(warehouseResultObj);
                                }
                                break;
                            case COST:
                                //todo 和产品确定成本的方案
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(COST, 0, fieldAttrEntity));
                                break;
                            case SPECIFICATION:
                                // 格式化规格
                                String specification = specificationModel.joinSpecification(entity.getSpecification());
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(SPECIFICATION, specification, fieldAttrEntity));
                                break;
                            case STOCK:
                                Double stock = data.getDouble(ProductEnum.STOCK.getAttr());
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(STOCK, stock, fieldAttrEntity));
                                break;
                            case BATCH:
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(BATCH, "", fieldAttrEntity));
                                break;
                            case GUARANTEE_PERIOD:
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(GUARANTEE_PERIOD, 0.0, fieldAttrEntity));
                                break;
                            case PRODUCE_DATE:
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(PRODUCE_DATE, "", fieldAttrEntity));
                                break;
                            case NUM:
                                if(Objects.isNull(fieldAttrEntity)) {
                                    fieldAttrEntity = new FieldAttrEntity();
                                }
                                FieldAttrEntity stockAttrEntity = nowProductExplainMap.get(ProductEnum.STOCK.getSaasAttr());
                                if(Objects.nonNull(stockAttrEntity)) {
                                    fieldAttrEntity.setAccuracy(stockAttrEntity.getAccuracy());
                                }
                                productNum = entity.getProductNum();
                                productNum = productNum == null ? 0 : productNum;
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(NUM, productNum, fieldAttrEntity));
                                break;
                            case UNIT:
                                String productUnit = entity.getProductUnit();
                                String unitStr = productModel.getProductUnitTextByValue(productUnit, fieldAttrEntity);
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(UNIT, unitStr, fieldAttrEntity));
                                break;
                            case MEMO:
                                JsonHelperUtil.addToJSONArray(attrArray, saasUpdateHelp.formatSelectProduct4Show(MEMO, "", fieldAttrEntity));
                                break;
                            default:
                        }
                        productObj.put("result", attrArray);
                        productObj.put(StringConstant.SAAS_LINK_BUSINESS_ID, entity.getProductId());
                        productObj.put(StringConstant.BUSINESS_PRODUCT_ID, entity.getId());
                        productObj.put("parentId", entity.getParentId());
                    }
                }
                productMap.put(entity.getSort(), productObj);
            }
            productArray.addAll(productMap.values());
            productFinalObj.put(StringConstant.PRODUCT_LIST, productArray);
        }
        dataList.put(WorkOrderEnum.SPARE_PARTS.getAttr(), productFinalObj);
    }

    @Override
    public ListAppVO formatWorkOrderAppList(FormDataListDTO formDataListDTO, List<WorkOrderEntityExt> workOrderEntityExts, Integer totalCount) throws XbbException {
        List<AppListPojo> appListPojos = new ArrayList<>();
        String corpid = formDataListDTO.getCorpid();
        String userId = formDataListDTO.getUserId();
        Integer saasMark = formDataListDTO.getSaasMark();
        Integer businessType = XbbRefTypeEnum.WORK_ORDER.getCode();
        boolean isInside = false;
        //不限时自由工单
        boolean isLimit = false;
        // 是否自由工单
        boolean isFree = false;
//        LOG.info("formatWorkOrderAppList workOrderEntityExts:=" + JSON.toJSONString(workOrderEntityExts));
//        if (Objects.nonNull(workOrderEntityExts) && workOrderEntityExts.size() > 0) {
//            WorkOrderEntityExt workOrderEntityExt = workOrderEntityExts.get(0);
//            Long templateId = workOrderEntityExt.getTemplateId();
//            if (templateId == null || templateId == 0L) {
//                LOG.info("workOrderError-----------workOrderEntityExt" + JSON.toJSONString(workOrderEntityExt) + "--------------");
//                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002);
//            }
//            WorkOrderTemplateEntity workOrderTemplateEntity = workOrderTemplateModel.getBykey(templateId, corpid);
//            LOG.info("workOrderError-----------workOrderTemplateEntity" + JSON.toJSONString(workOrderTemplateEntity) + "--------------");
//            String scopeRule = workOrderTemplateEntity.getScopeRule();
//            JSONObject scopeRuleObj = JSONObject.parseObject(scopeRule);
//            Integer inside = scopeRuleObj.getInteger("inside");
//            if (Objects.equals(inside, 1)) {
//                isInside = true;
//            }
//            if (Objects.equals(workOrderTemplateEntity.getIsFree(), 1) && Objects.equals(workOrderTemplateEntity.getExpectedTime(), 0)) {
//                isLimit = true;
//            }
//            isFree = Objects.equals(workOrderTemplateEntity.getIsFree(), 1);
//        }

        UserVO loginUser = formDataListDTO.getLoginUser();
        Set<RoleSimpleVO> roleSet = loginUser.getRoleSet();
        Set<String> permSet = loginUser.getPermSet();
        UserEntity userEntity = new UserEntity();
        BeanUtil.copyProperties(loginUser, userEntity);
        boolean isBoss = loginUser.isAdminOrBoss();
        boolean isWorkOrderManager = false;
        for (RoleSimpleVO roleSimpleVO : roleSet) {
            if (Objects.equals(roleSimpleVO.getId(), RoleEnum.WORKORDER_MANAGER.getCode())) {
                isWorkOrderManager = true;
                break;
            }
        }
        Map<Long, List<String>> workOrderCoopMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> workOrderCcMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Long> ids = new ArrayList<>();
        Set<Long> templateIds = new HashSet<>();
        Set<Long> formIds = new HashSet<>();
        for (WorkOrderEntityExt entityExt : workOrderEntityExts) {
            ids.add(entityExt.getId());
            templateIds.add(entityExt.getTemplateId());
            formIds.add(entityExt.getFormId());
        }

        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("corpid", corpid);
        params.put("dataIdIn", ids);
        params.put("del", 0);
        params.put("isMain", 0);
        List<WorkOrderFlowUserEntity> workOrderFlowUserEntityList = workOrderFlowUserModel.findEntitys(params);
        for (WorkOrderFlowUserEntity entity : workOrderFlowUserEntityList) {
            List<String> userIds;
            if (workOrderCoopMap.containsKey(entity.getDataId())) {
                userIds = workOrderCoopMap.get(entity.getDataId());
            } else {
                userIds = new ArrayList<>();
            }
            userIds.add(entity.getUserId());
            workOrderCoopMap.put(entity.getDataId(), userIds);
        }

        params.clear();
        params.put("corpid", corpid);
        params.put("workOrderIdIn", ids);
        params.put("del", 0);
        List<WorkOrderCcEntity> workOrderCcEntityList = workOrderCcModel.findEntitys(params);
        for (WorkOrderCcEntity entity : workOrderCcEntityList) {
            List<String> userIds;
            if (workOrderCcMap.containsKey(entity.getWorkOrderId())) {
                userIds = workOrderCcMap.get(entity.getWorkOrderId());
            } else {
                userIds = new ArrayList<>();
            }
            userIds.add(entity.getUserId());
            workOrderCcMap.put(entity.getWorkOrderId(), userIds);
        }

        Map<Long, WorkOrderTemplateEntity> templateMap = workOrderTemplateModel.getTemplateMap(templateIds, corpid);

        List<WorkOrderExplainEntity> workOrderExplainEntities = workOrderExplainModel.getByFormIdIn(formIds, corpid);
        Map<Long, FieldAttrEntity> formIdAndFieldAttrMap = new HashMap<>();
        for (WorkOrderExplainEntity workOrderExplainEntity : workOrderExplainEntities) {
            List<FieldAttrEntity> fieldAttrEntities = JSON.parseArray(workOrderExplainEntity.getExplains(), FieldAttrEntity.class);
            for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
                if (Objects.equals(fieldAttrEntity.getAttr(), WorkOrderEnum.CONTACT_INFORMATION.getAttr())) {
                    formIdAndFieldAttrMap.put(workOrderExplainEntity.getFormId(), fieldAttrEntity);
                }
            }
        }


        for (WorkOrderEntityExt entityExt : workOrderEntityExts) {
            WorkOrderTemplateEntity workOrderTemplateEntity = templateMap.get(entityExt.getTemplateId());
            String scopeRule = workOrderTemplateEntity.getScopeRule();
            JSONObject scopeRuleObj = JSONObject.parseObject(scopeRule);
            Integer inside = scopeRuleObj.getInteger("inside");
            if (Objects.equals(inside, 1)) {
                isInside = true;
            }
            isLimit = false;
            if (Objects.equals(workOrderTemplateEntity.getIsFree(), 1) && Objects.equals(workOrderTemplateEntity.getExpectedTime(), 0)) {
                isLimit = true;
            }
            isFree = Objects.equals(workOrderTemplateEntity.getIsFree(), 1);


            Long workOrderId = entityExt.getId();
            JSONObject data = entityExt.getData();
            Long appId = entityExt.getAppId();
            Long formId = entityExt.getFormId();

            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();
            JSONObject basics = new JSONObject();

            basics.put("appId", appId);
            basics.put("formId", formId);
            basics.put("saasMark", saasMark);
            basics.put("businessType", businessType);

            //角标
            String emergencyStr = ItemUtil.parseItemPoJoFromFormData2String(data, WorkOrderEnum.EMERGENCY_LEVEL.getAttr(), "");
            Integer emergency = WorkOrderEmergencyEnum.getByName(emergencyStr);
            if (emergency != null) {
                superScript.put("emergency", emergency);
            }
            //其他
            Integer status = entityExt.getStatus();
            String statusStr = WorkOrderStatusEnum.getByCode(status).getName();
            List<WorkOrderFlowNodeEntity> nodeList = workOrderFlowNodeModel.getNode(workOrderId, 1, corpid);
            WorkOrderFlowNodeEntity workOrderFlowNodeEntity = null;
            if (CollectionUtils.isNotEmpty(nodeList)) {
                workOrderFlowNodeEntity = nodeList.get(0);
            }
            if (formDataListDTO.getDefaultGroup().equals(1) && Objects.nonNull(workOrderFlowNodeEntity)) {
                ListGroupEnum listGroupEnum = ListGroupEnum.getByCode(formDataListDTO.getListGroupId().intValue());
                if (isLimit) {
                    others.put("consumeTime", "");
                    others.put("isOut", 0);
                } else {
                    if (Objects.equals(listGroupEnum, ListGroupEnum.WORK_ORDER_RESPONSE_BY_ME)) {
                        status = workOrderFlowNodeEntity.getStatus();
                        statusStr = WorkOrderNodeStatusEnum.getByCode(status).getName();
                        //我负责的列表看节点的时间
                        TimeConsumingOutPojo timeConsumingOutPojo = workOrderBasicService.workOrderNodeConsueTime(workOrderFlowNodeEntity);
                        others.put("consumeTime", timeConsumingOutPojo.getConsumeTimeStr());
                        others.put("isOut", timeConsumingOutPojo.getIsOut());
                    } else {
                        TimeConsumingOutPojo timeConsumingOutPojo = workOrderBasicService.workOrderConsueTime(entityExt);
                        others.put("consumeTime", timeConsumingOutPojo.getConsumeTimeStr());
                        others.put("isOut", timeConsumingOutPojo.getIsOut());
                    }
                }
            } else {
                if (isLimit) {
                    others.put("consumeTime", "");
                    others.put("isOut", 0);
                } else {
                    TimeConsumingOutPojo timeConsumingOutPojo = workOrderBasicService.workOrderConsueTime(entityExt);
                    others.put("consumeTime", timeConsumingOutPojo.getConsumeTimeStr());
                    others.put("isOut", timeConsumingOutPojo.getIsOut());
                }
            }
            boolean acceptButton = false;
            if (!Objects.isNull(workOrderFlowNodeEntity) && Objects.equals(workOrderFlowNodeEntity.getStatus(), WorkOrderNodeStatusEnum.UNACCEPTED.getCode())) {
                //接收 工单负责人、老板、超管等最高权限人员，工单主管。
                List<String> acceptUserIds = getAcceptUserIds(corpid, isFree, entityExt, workOrderFlowNodeEntity);
                boolean isMain = false;
                boolean isCoop = false;
                boolean isCc = false;
                List<String> coopUserIds = workOrderCoopMap.get(workOrderId);
                List<String> ccUserIds = workOrderCcMap.get(workOrderId);
                if (Objects.nonNull(coopUserIds) && coopUserIds.contains(userId)) {
                    isCoop = true;
                }
                if (Objects.nonNull(ccUserIds) && ccUserIds.contains(userId)) {
                    isCc = true;
                }
                boolean canRob = acceptUserIds.contains(userId);
                boolean isRob = Objects.equals(workOrderFlowNodeEntity.getNodeType(), WorkOrderFlowNodeTypeEnum.ROB_NODE.getCode());
                if ( isRob &&  canRob ) {
                    //为抢单节点，并没有人抢单
                    acceptButton = true;
                } else {
                    //当前节点为当前负责人
                    isMain = Objects.equals(workOrderFlowNodeEntity.getUserId(), userEntity.getUserId());
                    if (isMain || isBoss || isWorkOrderManager) {
                        acceptButton = true;
                    }
                }
            }
            boolean rateButton = false;
            if (Objects.equals(WorkOrderStatusEnum.FINISH.getCode(), status) && Objects.equals(WorkOrderNodeStatusEnum.FINISH.getCode(), workOrderFlowNodeEntity.getStatus())) {
                WorkOrderEvaluateEntity workOrderEvaluateEntity = workOrderEvaluateModel.getByWorkOrderId(workOrderId, corpid);
                if (Objects.isNull(workOrderEvaluateEntity) && isInside) {
                    //内部评价工单才可直接评论
                    //默认“工单主管”、超管、老板角色有权限评价
                    if (isBoss || (isWorkOrderManager && permSet.contains(ProPermissionAliasEnum.WORK_ORDER_RATE.getAlias())) || permSet.contains(ProPermissionAliasEnum.WORK_ORDER_RATE.getAlias())) {
                        rateButton = true;
                    }
                }
            }

            List<MobileDetailDialPhonePojo> phoneList = new ArrayList<>();
            JSONArray phoneArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, WorkOrderEnum.CONTACT_INFORMATION.getAttr(), new JSONArray());
            HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
            handlerExplainDTO.setLoginUser(loginUser);
            handlerExplainDTO.setUserId(loginUser.getUserId());
            handlerExplainDTO.setCreatorId(entityExt.getCreatorId());
            handlerExplainDTO.setOwnerId(workOrderFlowNodeEntity == null ? new ArrayList<>() : Collections.singletonList(workOrderFlowNodeEntity.getUserId()));
            handlerExplainDTO.setCoUserId(workOrderCcMap.get(workOrderId));

            FieldAttrEntity subFormAttr = commonHelp.getSubFormAttr(formIdAndFieldAttrMap.get(entityExt.getFormId()));
            phoneList.addAll(mobileDetailService.handleDialPhone(phoneArray, null, RedundantTemplateTypeEnum.WORKORDER.getCode(), entityExt.getId(), handlerExplainDTO,subFormAttr, handlerExplainDTO.getLoginUser()));
            others.put("phone", phoneList);
            others.put("statusStr", statusStr);
            others.put("status", status);
            others.put("acceptButton", acceptButton);
            others.put("rateButton",rateButton);
            others.put("rateStar", data.getIntValue(WorkOrderEnum.RATE_STAR.getAttr()));

            List<SummaryDataPoJo> summaryList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.SUMMARY_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            List<SummaryDataPoJo> lablesList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.LABELS_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            List<FormTitlePoJo> titleList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.TITLE_LIST, new JSONArray()).toJavaList(FormTitlePoJo.class);
            appListPojos.add(new AppListPojo(workOrderId, titleList, summaryList, superScript, lablesList, others, basics));
        }
        ListAppVO listAppVO = new ListAppVO();
        listAppVO.setList(appListPojos);
        listAppVO.setTotalCount(totalCount);
        return listAppVO;
    }

    /**
     * 获取可接收工单人员
     * @param corpid 公司id
     * @param isFree 是否自由工单
     * @param entity 工单实体
     * @param workOrderFlowNodeEntity 当前工作流节点实体
     * @return  可接收人员
     */
    @Override
    public List<String> getAcceptUserIds(String corpid, boolean isFree, WorkOrderEntity entity, WorkOrderFlowNodeEntity workOrderFlowNodeEntity) {
        List<String> acceptUserIds = new ArrayList<>();
        if (isFree) {
            // 自由流程
            acceptUserIds.add(workOrderFlowNodeEntity.getUserId());
            return acceptUserIds;
        }
        // 指定流程
        WorkOrderStageEntity workOrderStageEntity = workOrderStageModel.getByKey(entity.getNowStageId(), corpid);
        if (workOrderStageEntity == null) {
            acceptUserIds.add(workOrderFlowNodeEntity.getUserId());
            return acceptUserIds;
        }
        WorkOrderStageRuleEnum workOrderStageRuleEnum = WorkOrderStageRuleEnum.getByCode(workOrderStageEntity.getRuleId());
        WorkOrderStageRobTypeEnum workOrderStageRobTypeEnum = WorkOrderStageRobTypeEnum.getByCode(workOrderStageEntity.getRefRobType());
        if (workOrderStageRuleEnum == null || workOrderStageRobTypeEnum == null) {
            acceptUserIds.add(workOrderFlowNodeEntity.getUserId());
            return acceptUserIds;
        }
        switch (workOrderStageRuleEnum) {
            case ROB:
                switch (workOrderStageRobTypeEnum) {
                    case USER:
                        break;
                    case SERVICE:
                        acceptUserIds.addAll(workOrderBasicService.getServiceUserIdList(corpid, workOrderStageEntity.getRefRobId()));
                        break;
                    case DEPARTMENT:
                        acceptUserIds.addAll(workOrderBasicService.getDepartmentUserIdList(corpid, workOrderStageEntity.getRefRobId()));
                        break;
                    default:
                        break;
                }
                break;
            default:
                acceptUserIds.add(workOrderFlowNodeEntity.getUserId());
                break;
        }

        return acceptUserIds;
    }

    @Override
    public ListAppVO formatWorkOrderRecord(FormDataListDTO formDataListDTO, List<WorkOrderEntityExt> workOrderEntityExts, Integer totalCount) throws XbbException {
        List<AppListPojo> appListPojos = new ArrayList<>();
        String corpid = formDataListDTO.getCorpid();
        String userId = formDataListDTO.getUserId();
        Integer saasMark = formDataListDTO.getSaasMark();
        Integer businessType = XbbRefTypeEnum.WORK_ORDER.getCode();
        String name;
        boolean isInside = false;
        //不限时自由工单
        boolean isLimit = false;
        if (Objects.nonNull(workOrderEntityExts) && workOrderEntityExts.size() > 0) {
            WorkOrderEntityExt workOrderEntityExt = workOrderEntityExts.get(0);
            WorkOrderTemplateEntity workOrderTemplateEntity = workOrderTemplateModel.getBykey(workOrderEntityExt.getTemplateId(), corpid);
            String scopeRule = workOrderTemplateEntity.getScopeRule();
            JSONObject scopeRuleObj = JSONObject.parseObject(scopeRule);
            Integer inside = scopeRuleObj.getInteger("inside");
            if (Objects.equals(inside, 1)) {
                isInside = true;
            }
            if (Objects.equals(workOrderTemplateEntity.getIsFree(), 1) && Objects.equals(workOrderTemplateEntity.getExpectedTime(), 0)) {
                isLimit = true;
            }
        }

        UserVO loginUser = formDataListDTO.getLoginUser();
        Set<RoleSimpleVO> roleSet = loginUser.getRoleSet();
        Set<String> permSet = loginUser.getPermSet();
        UserEntity userEntity = new UserEntity();
        BeanUtil.copyProperties(loginUser, userEntity);
        boolean isBoss = userModel.isBoss(userEntity);
        boolean isWorkOrderManager = false;
        for (RoleSimpleVO roleSimpleVO : roleSet) {
            if (Objects.equals(roleSimpleVO.getId(), RoleEnum.WORKORDER_MANAGER.getCode())) {
                isWorkOrderManager = true;
            }
        }
        Map<Long, List<String>> workOrderCoopMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> workOrderCcMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Long> ids = new ArrayList<>();
        List<Long> formIds = new ArrayList<>();
        for (WorkOrderEntityExt entityExt : workOrderEntityExts) {
            ids.add(entityExt.getId());
            formIds.add(entityExt.getFormId());
        }
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("corpid", corpid);
        params.put("dataIdIn", ids);
        params.put("del", 0);
        params.put("isMain", 0);
        List<WorkOrderFlowUserEntity> workOrderFlowUserEntityList = workOrderFlowUserModel.findEntitys(params);
        for (WorkOrderFlowUserEntity entity : workOrderFlowUserEntityList) {
            List<String> userIds;
            if (workOrderCoopMap.containsKey(entity.getDataId())) {
                userIds = workOrderCoopMap.get(entity.getDataId());
            } else {
                userIds = new ArrayList<>();
            }
            userIds.add(entity.getUserId());
            workOrderCoopMap.put(entity.getDataId(), userIds);
        }

        params.clear();
        params.put("corpid", corpid);
        params.put("workOrderIdIn", ids);
        params.put("del", 0);
        List<WorkOrderCcEntity> workOrderCcEntityList = workOrderCcModel.findEntitys(params);
        for (WorkOrderCcEntity entity : workOrderCcEntityList) {
            List<String> userIds;
            if (workOrderCcMap.containsKey(entity.getWorkOrderId())) {
                userIds = workOrderCcMap.get(entity.getWorkOrderId());
            } else {
                userIds = new ArrayList<>();
            }
            userIds.add(entity.getUserId());
            workOrderCcMap.put(entity.getWorkOrderId(), userIds);
        }

        List<WorkOrderExplainEntity> workOrderExplainEntities = workOrderExplainModel.getByFormIdIn(formIds, corpid);
        Map<Long, FieldAttrEntity> formIdAndFieldAttrMap = new HashMap<>();
        for (WorkOrderExplainEntity workOrderExplainEntity : workOrderExplainEntities) {
            List<FieldAttrEntity> fieldAttrEntities = JSON.parseArray(workOrderExplainEntity.getExplains(), FieldAttrEntity.class);
            for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
                if (Objects.equals(fieldAttrEntity.getAttr(), WorkOrderEnum.CONTACT_INFORMATION.getAttr())) {
                    formIdAndFieldAttrMap.put(workOrderExplainEntity.getFormId(), fieldAttrEntity);
                }
            }
        }

        for (WorkOrderEntityExt entityExt : workOrderEntityExts) {
            List<SummaryDataPoJo> summaryList = new ArrayList<>();
            List<FormTitlePoJo> titleList = new ArrayList<>();

            Long workOrderId = entityExt.getId();
            JSONObject data = entityExt.getData();
            Long appId = entityExt.getAppId();
            Long formId = entityExt.getFormId();
            if (data.containsKey(WorkOrderEnum.NAME.getAttr()) && data.get(WorkOrderEnum.NAME.getAttr())!= null) {
                String attr = WorkOrderEnum.NAME.getAttr();
                Object value = data.get(attr);
                name = value.toString();
            } else {
                name = entityExt.workOrderName();
            }

            JSONArray explains = new JSONArray();
            JSONObject superScript = new JSONObject();
            JSONArray tags = new JSONArray();
            JSONObject others = new JSONObject();
            JSONObject basics = new JSONObject();

            basics.put("appId", appId);
            basics.put("formId", formId);
            basics.put("saasMark", saasMark);
            basics.put("businessType", businessType);

            //工单编号
            String sheetNo = entityExt.getSerialNo();
            // 联系人/电话
//            String contactName = FastJsonHelper.getStringOrDefaultFromFormData(data, WorkOrderEnum.CONTACT_INFORMATION.getAttr(), "无");
            //实施时间
            String implementationTimeStr = I18nMessageUtil.getMessage(CommonConstant.NOTHING);
            Long implementationTime = FastJsonHelper.getLongOrDefaultFromFormData(data, WorkOrderEnum.IMPLEMENTATION_TIME.getAttr(), 0L);
            if (!implementationTime.equals(0L)) {
                implementationTimeStr = DateTimeUtil.getStringEpochSecond(implementationTime);
            }
            //实施地址
            String address = commonHelp.formatAddress(data, WorkOrderEnum.ADDRESS.getAttr());
            //解释
            /*explains.add("工单编号:" + sheetNo);
//            explains.add("联系人:" + contactName);
            explains.add("实施时间:" + implementationTimeStr);
            explains.add("地址:" + address);*/
            summaryList.add(commonHelp.setSummary(WorkOrderEnum.SHEET_NO.getAttrName(), sheetNo));
            summaryList.add(commonHelp.setSummary(WorkOrderEnum.IMPLEMENTATION_TIME.getAttrName(), implementationTimeStr));
            summaryList.add(commonHelp.setSummary(WorkOrderEnum.ADDRESS.getAttrName(), address));
            //角标
            Integer emergency = getIntegerOrDefaultFromFormData(data, WorkOrderEnum.EMERGENCY_LEVEL.getAttr(), 0);
            superScript.put("emergency", emergency);
            //其他
            Integer status = entityExt.getStatus();
            String statusStr = WorkOrderStatusEnum.getByCode(status).getName();
            WorkOrderFlowNodeEntity workOrderFlowNodeEntity = workOrderFlowNodeModel.getNode(workOrderId, 1, corpid).get(0);
            if (formDataListDTO.getDefaultGroup().equals(1)) {
                ListGroupEnum listGroupEnum = ListGroupEnum.getByCode(formDataListDTO.getListGroupId().intValue());
                if (isLimit) {
                    others.put("consumeTime", "");
                    others.put("isOut", 0);
                } else {
                    if (Objects.equals(listGroupEnum, ListGroupEnum.WORK_ORDER_RESPONSE_BY_ME)) {
                        status = workOrderFlowNodeEntity.getStatus();
                        statusStr = WorkOrderNodeStatusEnum.getByCode(status).getName();
                        //我负责的列表看节点的时间
                        TimeConsumingOutPojo timeConsumingOutPojo = workOrderBasicService.workOrderNodeConsueTime(workOrderFlowNodeEntity);
                        others.put("consumeTime", timeConsumingOutPojo.getConsumeTimeStr());
                        others.put("isOut", timeConsumingOutPojo.getIsOut());
                    } else {
                        TimeConsumingOutPojo timeConsumingOutPojo = workOrderBasicService.workOrderConsueTime(entityExt);
                        others.put("consumeTime", timeConsumingOutPojo.getConsumeTimeStr());
                        others.put("isOut", timeConsumingOutPojo.getIsOut());
                    }
                }
            } else {
                if (isLimit) {
                    others.put("consumeTime", "");
                    others.put("isOut", 0);
                } else {
                    TimeConsumingOutPojo timeConsumingOutPojo = workOrderBasicService.workOrderConsueTime(entityExt);
                    others.put("consumeTime", timeConsumingOutPojo.getConsumeTimeStr());
                    others.put("isOut", timeConsumingOutPojo.getIsOut());
                }
            }
            boolean acceptButton = false;
            if (!Objects.isNull(workOrderFlowNodeEntity) && Objects.equals(workOrderFlowNodeEntity.getStatus(), WorkOrderNodeStatusEnum.UNACCEPTED.getCode())) {
                //接收 工单负责人、老板、超管等最高权限人员，工单主管。
                boolean isMain = false;
                boolean isCoop = false;
                boolean isCc = false;
                List<String> coopUserIds = workOrderCoopMap.get(workOrderId);
                List<String> ccUserIds = workOrderCcMap.get(workOrderId);
                if (Objects.nonNull(coopUserIds) && coopUserIds.contains(userId)) {
                    isCoop = true;
                }
                if (Objects.nonNull(ccUserIds) && ccUserIds.contains(userId)) {
                    isCc = true;
                }
                if (Objects.equals(workOrderFlowNodeEntity.getNodeType(), WorkOrderFlowNodeTypeEnum.ROB_NODE.getCode()) && (Objects.isNull(workOrderFlowNodeEntity.getUserId()) || workOrderFlowNodeEntity.getUserId().length() == 0) || (!isCc && !isCoop)) {
                    //为抢单节点，并没有人抢单
                    acceptButton = true;
                } else {
                    //当前节点为当前负责人
                    isMain = Objects.equals(workOrderFlowNodeEntity.getUserId(), userEntity.getUserId());
                    if (isMain || isBoss || isWorkOrderManager) {
                        acceptButton = true;
                    }
                }
            }
            boolean rateButton = false;
            if (Objects.equals(WorkOrderStatusEnum.FINISH.getCode(), entityExt.getStatus()) && Objects.nonNull(workOrderFlowNodeEntity) && Objects.equals(WorkOrderNodeStatusEnum.FINISH.getCode(), workOrderFlowNodeEntity.getStatus())) {
                WorkOrderEvaluateEntity workOrderEvaluateEntity = workOrderEvaluateModel.getByWorkOrderId(workOrderId, corpid);
                if (Objects.isNull(workOrderEvaluateEntity) && isInside) {
                    //内部评价工单才可直接评论
                    //默认“工单主管”、超管、老板角色有权限评价
                    if (isBoss || (isWorkOrderManager && permSet.contains(ProPermissionAliasEnum.WORK_ORDER_RATE.getAlias()))) {
                        rateButton = true;
                    }
                }
            }

            List<MobileDetailDialPhonePojo> phoneList = new ArrayList<>();
            JSONArray phoneArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, WorkOrderEnum.CONTACT_INFORMATION.getAttr(), new JSONArray());
            FieldAttrEntity subFormAttr = commonHelp.getSubFormAttr(formIdAndFieldAttrMap.get(entityExt.getFormId()));
            phoneList.addAll(mobileDetailService.handleDialPhone(phoneArray, null, RedundantTemplateTypeEnum.WORKORDER.getCode(), entityExt.getId(),null,subFormAttr, formDataListDTO.getLoginUser()));
            others.put("phone", phoneList);
            others.put("statusStr", statusStr);
            others.put("status", status);
            others.put("acceptButton", acceptButton);
            others.put("rateButton",rateButton);
            others.put("rateStar", data.getIntValue(WorkOrderEnum.RATE_STAR.getAttr()));

            titleList.add(commonHelp.setTitle(name));
            appListPojos.add(new AppListPojo(workOrderId, titleList, summaryList, superScript, new ArrayList<>(), others, basics));
        }
        ListAppVO listAppVO = new ListAppVO();
        listAppVO.setList(appListPojos);
        listAppVO.setTotalCount(totalCount);
        return listAppVO;
    }

    @Override
    public DetailTabGetVO formatWorkOrderWebList(FormDataListDTO formDataListDTO, List<WorkOrderEntityExt> workOrderEntityExts, Integer totalCount) throws XbbException {
        DetailTabGetVO detailTabGetVO = new DetailTabGetVO();
        JSONArray needShowAttrArr = new JSONArray();
        String corpid = formDataListDTO.getCorpid();
        String userId = formDataListDTO.getUserId();
        Integer saasMark = formDataListDTO.getSaasMark();
        Integer businessType = XbbRefTypeEnum.WORK_ORDER.getCode();
        String name;

        Set<Long> formIds = new HashSet<>();
        for (WorkOrderEntityExt entityExt : workOrderEntityExts) {
            formIds.add(entityExt.getFormId());
        }
        List<WorkOrderExplainEntity> workOrderExplainEntities = workOrderExplainModel.getByFormIdIn(formIds, corpid);
        Map<Long, FieldAttrEntity> formIdAndFieldAttrMap = new HashMap<>();
        for (WorkOrderExplainEntity workOrderExplainEntity : workOrderExplainEntities) {
            List<FieldAttrEntity> fieldAttrEntities = JSON.parseArray(workOrderExplainEntity.getExplains(), FieldAttrEntity.class);
            for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
                if (Objects.equals(fieldAttrEntity.getAttr(), WorkOrderEnum.CONTACT_INFORMATION.getAttr())) {
                    formIdAndFieldAttrMap.put(workOrderExplainEntity.getFormId(), fieldAttrEntity);
                }
            }
        }

        for (WorkOrderEntityExt entityExt : workOrderEntityExts) {
            JSONObject needShowAttr = new JSONObject();
            Long workOrderId = entityExt.getId();
            JSONObject data = entityExt.getData();
            Long appId = entityExt.getAppId();
            Long formId = entityExt.getFormId();
            Long dataId = entityExt.getDataId();
            if (data.containsKey(WorkOrderEnum.NAME.getAttr()) && data.get(WorkOrderEnum.NAME.getAttr())!= null) {
                String attr = WorkOrderEnum.NAME.getAttr();
                Object value = data.get(attr);
                name = value.toString();
            } else {
                name = entityExt.workOrderName();
            }
            needShowAttr.put(TabConstant.NAME, name);
            needShowAttr.put("id", entityExt.getId());

            // 中部内容
            JSONObject centent = new JSONObject();
            // 底部
            JSONArray summaryList = new JSONArray();
            JSONObject entity = new JSONObject();
            JSONObject statusObj1 = new JSONObject();
            JSONArray statusList = new JSONArray();

            entity.put("appId", appId);
            entity.put("formId", formId);
            entity.put("saasMark", saasMark);
            entity.put("businessType", businessType);
            entity.put("dataId", dataId);

            needShowAttr.put("entity", entity);

            //工单编号
            String sheetNo = entityExt.getSerialNo();
            // 联系人/电话
//            String contactName = FastJsonHelper.getStringOrDefaultFromFormData(data, WorkOrderEnum.CONTACT_INFORMATION.getAttr(), "无");
            //实施时间
            String implementationTimeStr = I18nMessageUtil.getMessage(CommonConstant.NOTHING);
            Long implementationTime = FastJsonHelper.getLongOrDefaultFromFormData(data, WorkOrderEnum.IMPLEMENTATION_TIME.getAttr(), 0L);
            if (!implementationTime.equals(0L)) {
                implementationTimeStr = DateTimeUtil.getStringEpochSecond(implementationTime);
            }
            //实施地址
            JSONObject addressObj = FastJsonHelper.getJsonObjectOrDefaultFromFormData(data, WorkOrderEnum.ADDRESS.getAttr(),  new JSONObject());
            String address = addressObj.getOrDefault(PaasConstant.PROVINCE, "").toString() + addressObj.getOrDefault(PaasConstant.CITY, "").toString() + addressObj.getOrDefault(PaasConstant.DISTRICT, "").toString() + addressObj.getOrDefault(PaasConstant.ADDRESS, "").toString();
            //角标
            Integer emergency = getIntegerOrDefaultFromFormData(data, WorkOrderEnum.EMERGENCY_LEVEL.getAttr(), 0);
            needShowAttr.put("emergency", emergency);
            //其他
            Integer status = entityExt.getStatus();
            String statusStr = WorkOrderStatusEnum.getByCode(status).getName();
            Long date = entityExt.getAddTime();
            WorkOrderFlowNodeEntity workOrderFlowNodeEntity = workOrderFlowNodeModel.getNode(workOrderId, 1, corpid).get(0);
            if (formDataListDTO.getDefaultGroup().equals(1)) {
                ListGroupEnum listGroupEnum = ListGroupEnum.getByCode(formDataListDTO.getListGroupId().intValue());
                if (Objects.equals(listGroupEnum, ListGroupEnum.WORK_ORDER_RESPONSE_BY_ME)) {
                    status = workOrderFlowNodeEntity.getStatus();
                    statusStr = WorkOrderNodeStatusEnum.getByCode(status).getName();
                    //我负责的列表看节点的时间
                    TimeConsumingOutPojo timeConsumingOutPojo = workOrderBasicService.workOrderNodeConsueTime(workOrderFlowNodeEntity);
                    centent.put("consumeTime", timeConsumingOutPojo.getConsumeTimeStr());
                    centent.put("isOut", timeConsumingOutPojo.getIsOut());
                } else {
                    TimeConsumingOutPojo timeConsumingOutPojo = workOrderBasicService.workOrderConsueTime(entityExt);
                    centent.put("consumeTime", timeConsumingOutPojo.getConsumeTimeStr());
                    centent.put("isOut", timeConsumingOutPojo.getIsOut());
                }
            } else {
                TimeConsumingOutPojo timeConsumingOutPojo = workOrderBasicService.workOrderConsueTime(entityExt);
                centent.put("consumeTime", timeConsumingOutPojo.getConsumeTimeStr());
                centent.put("isOut", timeConsumingOutPojo.getIsOut());
            }
            needShowAttr.put(TabConstant.CONTENT, centent);

            List<MobileDetailDialPhonePojo> phoneList = new ArrayList<>();
            JSONArray phoneArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, WorkOrderEnum.CONTACT_INFORMATION.getAttr(), new JSONArray());
            FieldAttrEntity subFormAttr = commonHelp.getSubFormAttr(formIdAndFieldAttrMap.get(entityExt.getFormId()));
            phoneList.addAll(mobileDetailService.handleDialPhone(phoneArray, null, RedundantTemplateTypeEnum.WORKORDER.getCode(), entityExt.getId(),null,subFormAttr, formDataListDTO.getLoginUser()));
            statusObj1.put("value", statusStr);
            statusObj1.put("status", status);
            statusObj1.put("type", DetailTabStatusColorEnum.NORMAL.getAlias());
            statusList.add(statusObj1);
            //web端就展示第一个号码
            String telNum = "";
            if (phoneList.size()!= 0) {
                telNum = phoneList.get(0).getTelNum();
            }
            //工单编号
            JSONObject summaryObj1 = new JSONObject();
            summaryObj1.put(TabConstant.ATTR, WorkOrderEnum.SHEET_NO.getAttr());
            summaryObj1.put(TabConstant.ATTR_NAME, WorkOrderEnum.SHEET_NO.getAttrName());
            summaryObj1.put(TabConstant.VALUE, sheetNo);
            summaryList.add(summaryObj1);
            //实施时间
            JSONObject summaryObj2 = new JSONObject();
            summaryObj2.put(TabConstant.ATTR, WorkOrderEnum.IMPLEMENTATION_TIME.getAttr());
            summaryObj2.put(TabConstant.ATTR_NAME, WorkOrderEnum.IMPLEMENTATION_TIME.getAttrName());
            summaryObj2.put(TabConstant.VALUE, implementationTimeStr);
            summaryList.add(summaryObj2);
            //实施地址
            JSONObject summaryObj3 = new JSONObject();
            summaryObj3.put(TabConstant.ATTR, WorkOrderEnum.ADDRESS.getAttr());
            summaryObj3.put(TabConstant.ATTR_NAME, WorkOrderEnum.ADDRESS.getAttrName());
            summaryObj3.put(TabConstant.VALUE, address);
            summaryList.add(summaryObj3);
            //联系电话
            JSONObject summaryObj4 = new JSONObject();
            summaryObj4.put(TabConstant.ATTR, WorkOrderEnum.CONTACT_INFORMATION.getAttr());
            summaryObj4.put(TabConstant.ATTR_NAME, WorkOrderEnum.CONTACT_INFORMATION.getAttrName());
            summaryObj4.put(TabConstant.VALUE, telNum);
            summaryList.add(summaryObj4);
            Integer rateStar = null;
            if (data.getIntValue(WorkOrderEnum.RATE_STAR.getAttr()) != 0) {
                rateStar = data.getIntValue(WorkOrderEnum.RATE_STAR.getAttr());
            }
            needShowAttr.put("rateStar", rateStar);
            needShowAttr.put(TabConstant.SUMMARY_LIST, summaryList);
            needShowAttr.put(TabConstant.STATUS_LIST, statusList);
            needShowAttr.put(TabConstant.DATE_FORMAT, DateTimeUtil.getDateStringEpochSecond(date));
            needShowAttrArr.add(needShowAttr);
        }
        detailTabGetVO.setNeedShowAttr(needShowAttrArr);
        return detailTabGetVO;
    }


    @Override
    public WorkOrderDeleteBatchVO deleteBatch(WorkOrderDeleteBatchDTO workOrderDeleteBatchDTO) throws XbbException {
        WorkOrderDeleteBatchVO workOrderDeleteBatchVO = new WorkOrderDeleteBatchVO();
        try {
            // TODO 删除权限校验
            // TODO 如果该工单有出库单在审批中（待审批或审批中）则不让删除工单(批量时只要有一个有问题就返回错误)
            List<Long> idIn = workOrderDeleteBatchDTO.getDataIdList();
            String corpid = workOrderDeleteBatchDTO.getCorpid();
            //工单下游单据校验，有出库单就不允许删除
            List<Long> hasDownstreamList = outstockService.hasDownstreamList(corpid,idIn,OutstockTypeEnum.WORK_ORDER_OUTSTOCK.getCode());
            delErrorMsg(corpid,hasDownstreamList);
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(StringConstant.CORPID, corpid);
            param.put("idIn", idIn);
            List<WorkOrderEntity> workOrderEntityList = workOrderModel.findEntitys(param);
            if (Objects.isNull(workOrderEntityList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            List<Long> physicalDelIds = new ArrayList<>();
            physicalDelIds.addAll(idIn);
            List<Long> deleteIdIn = new ArrayList<>();
            //查询名称
            List<String> workOrderName= new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

            UserVO loginUser = workOrderDeleteBatchDTO.getLoginUser();
            Map<Long, List<String>> pushUserIdMap = new HashMap<>();
            for (WorkOrderEntity entity : workOrderEntityList) {
                List<String> pushUserIds = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.WORKORDER_DEL_PUSH.getCode(), PushTypeEnum.WORKORDER_DEL_PUSH.getSubCode(), loginUser, entity);
                pushUserIdMap.put(entity.getId(), pushUserIds);

                deleteIdIn.add(entity.getId());
                if (physicalDelIds.contains(entity.getId())) {
                    physicalDelIds.remove(entity.getId());
                }
                //查询编号+名称
                String name = entity.workOrderName();
                workOrderName.add(name);
            }
            if (!physicalDelIds.isEmpty()) {
                if(BasicConstant.ONE.equals(workOrderDeleteBatchDTO.getSingleFlag())
                        && BasicConstant.ONE.equals(physicalDelIds.size())){
                    paasEsModel.delete(physicalDelIds.get(0),corpid,IndexTypeEnum.IDX_SAAS_WORK_ORDER,null);
                }else {
                    // 删除es中存在，数据库不存在的数据
                    paasEsModel.deleteBatch(physicalDelIds, corpid, DelEnum.DELETE.getDel(), IndexTypeEnum.IDX_SAAS_WORK_ORDER);
                }
            }

            if (!deleteIdIn.isEmpty()) {
                if(BasicConstant.ONE.equals(workOrderDeleteBatchDTO.getSingleFlag())
                        && BasicConstant.ONE.equals(physicalDelIds.size())){
                    workOrderModel.deleteByKey(deleteIdIn.get(0),corpid);
                }else {
                    workOrderModel.deleteBatch(deleteIdIn, corpid);
                }
                workOrderDeleteBatchVO.setDeleteIds(deleteIdIn);
                //工单产品删除
                workOrderProductModel.deleteByWorkOrderIdIn(deleteIdIn, corpid);
                //工单工作流删除,节点删除
                workOrderFlowNodeModel.deleteByWorkOrderIdIn(deleteIdIn, corpid);
                //工单团队删除
                workOrderFlowUserModel.batchDeleteByWorkOrderId(corpid, deleteIdIn, null);

            }
            // TODO: 2019/5/9  出库单老逻辑没删除,新的不知道要不要 ,产品凤娇说不删  @date 2019/5/9 11:26

            // TODO 删除相关审批记录

            // 工单删除消息推送
            for (WorkOrderEntity entity : workOrderEntityList) {
                PushRefTypePojo.Options options = new PushRefTypePojo.Options(entity.getAppId(), entity.getMenuId(), entity.getFormId(), entity.getId(), SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.WORK_ORDER.getCode());
                List<String> pushUserIds = pushUserIdMap.get(entity.getId());
                if (Objects.nonNull(pushUserIds) && pushUserIds.size() > 0) {
                    MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserIds, Collections.singletonList(entity.getId()), 0, null, I18nMessageUtil.getMessage(WorkOrderPushConstant.WORK_ORDER_DEL_TITLE), String.format(I18nMessageUtil.getMessage(WorkOrderPushConstant.PUSH_DEL), loginUser.getName(), entity.getSerialNo()), null, options);
                    baseProducer.sendMessage(PushTypeEnum.WORKORDER_DEL_PUSH, messageRabbitMqDTO);
                }
            }

            // 删除工单动态
            try {
                if(!Objects.equals(DistributorMarkEnum.DISTRIBUTOR.getCode(),workOrderDeleteBatchDTO.getDistributorMark())) {
                    DynamicStrategy dynamicStrategy = dynamicStrategyFactory.getDynamicStrategy(ProjectLogEnum.WORK_ORDER_DELETE.getSubType());
                    FormDataDeleteBatchDTO formDataDeleteBatchDTO = BeanUtil.copyProperties(workOrderDeleteBatchDTO, FormDataDeleteBatchDTO.class, true);
                    List<PaasFormDataEntityExt> allowDeletePaasFormDatas = new ArrayList<>(workOrderEntityList.size());
                    BeanUtil.copyPropertiesList(workOrderEntityList, allowDeletePaasFormDatas, PaasFormDataEntityExt.class);
                    dynamicStrategy.batchDelete(DynamicDeleteDTO.initDynamicDeleteDTO(formDataDeleteBatchDTO, workOrderEntityList.stream().map(WorkOrderEntity::getId).collect(Collectors.toList()), allowDeletePaasFormDatas));
                }
            } catch (Exception e) {
                LOG.error("删除工单动态失败：", e);
            }

            OperateTypeEnum operateTypeEnum = OperateTypeEnum.DELETE;
            if (Objects.equals(1, workOrderDeleteBatchDTO.getIsBusinessRule())) {
                operateTypeEnum = OperateTypeEnum.RULE_DELETE;
            }
            //生成删除日志(区分单个删除和批量删除)
            String userId = workOrderDeleteBatchDTO.getUserId();
            String userName = workOrderDeleteBatchDTO.getLoginUserName();
            String nameStr = StringUtils.join(workOrderName, "，");
            if(deleteIdIn.size() > 1){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DELETE_FORM_DETAIL), userName, XbbRefTypeEnum.WORK_ORDER.getName(), deleteIdIn.size());
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(WorkOrderEnum.SHEET_NO.getAttrName());
                infoArrPojo.setContent(nameStr);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.WORK, operateTypeEnum,
                        "", "", memo, workOrderDeleteBatchDTO.getHttpHeader());
            } else if (Objects.equals(deleteIdIn.size(), 1)){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), userName, XbbRefTypeEnum.WORK_ORDER.getName(), nameStr);
                mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.WORK, operateTypeEnum,
                        deleteIdIn.get(0).toString(), nameStr, memo, workOrderDeleteBatchDTO.getHttpHeader());
            }
            
            

        } catch (XbbException e){
            throw e;
        }catch (Exception e) {
            LOG.error("WorkOrderServiceImpl.deleteBatch 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return workOrderDeleteBatchVO;
    }

    /**
     * 批量删除工单，只要有工单拥有下游单据，就报错不允许删除
     * @param corpid
     * @param hasDownstreamList
     */
    private void delErrorMsg(String corpid, List<Long> hasDownstreamList) throws XbbException {
        if (!hasDownstreamList.isEmpty()){
            Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put(StringConstant.CORPID,corpid);
            map.put("idIn",hasDownstreamList);
            map.put("columns","serial_no");
            List<WorkOrderEntity> workOrderEntityList = workOrderModel.findEntitys(map);
            StringBuilder stringBuilder = new StringBuilder();
            workOrderEntityList.forEach(item -> stringBuilder.append(item.getSerialNo()).append(","));
            throw new XbbException(WorkOrderErrorCodeEnum.API_ERROR_222070, String.format(WorkOrderErrorCodeEnum.API_ERROR_222070.getMsg(),stringBuilder.toString()));
        }
    }

    @Override
    public WorkOrderEditAttrUpdateVO batchEditAttr(WorkOrderEditAttrUpdateDTO workOrderEditAttrUpdateDTO) throws XbbException {
        WorkOrderEditAttrUpdateVO workOrderEditAttrUpdateVO = new WorkOrderEditAttrUpdateVO();
        try {
            // TODO 权限校验
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", workOrderEditAttrUpdateDTO.getCorpid());
            param.put("ids", workOrderEditAttrUpdateDTO.getDataIdList());
            List<WorkOrderEntity> workOrderList = workOrderModel.findEntitys(param);
            if (Objects.isNull(workOrderList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            // 审批通过后是否允许编辑
            Map<Long, Boolean> editAfterFinishedMap = paasProcessTemplateModel.getEditAfterFinishedMap(workOrderEditAttrUpdateDTO.getCorpid(),workOrderEditAttrUpdateDTO.getAppId(), workOrderEditAttrUpdateDTO.getMenuId(), workOrderEditAttrUpdateDTO.getLoginUser());
            List<PaasFormDataEntityExt> dataList = new ArrayList<>();
            BeanUtil.copyPropertiesList(workOrderList,dataList,PaasFormDataEntityExt.class);
            // 审批后能否编辑
            paasProcessTemplateModel.checkEditAfterFinished(editAfterFinishedMap, dataList);

            Boolean isFieldDependence = workOrderEditAttrUpdateDTO.getIsFieldDependence();
            AttrValuePojo singleAttrValuePojo = ProSaveHelp.getSingleAttrValuePojo(isFieldDependence, workOrderEditAttrUpdateDTO.getFieldEditedList());
            if (Objects.equals(singleAttrValuePojo.getAttr(), WorkOrderEnum.SERVICE_PRICE.getAttr())) {
                Object value = singleAttrValuePojo.getValue();
                if (Objects.isNull(value)) {
                    throw new XbbException(WorkOrderErrorCodeEnum.API_ERROR_222065);
                }
                Double servicePrice = Double.valueOf(value.toString());
                if (servicePrice < 0) {
                    throw new XbbException(WorkOrderErrorCodeEnum.API_ERROR_222059);
                }
            }

            //工单完成状态可编辑权限
            Boolean isWorkOrderFinishedEdit = ProPermissionHelp.hasThisPermission(workOrderEditAttrUpdateDTO.getLoginUser(),ProPermissionAliasEnum.WORK_ORDER_FINISHED_EDIT.getAlias());
            //不可编辑计数
            List<PaasFormDataEntityExt> noEditList = new ArrayList<>();
            if(!isWorkOrderFinishedEdit){
                workOrderList.forEach(workOrderEntity -> {
                    if (Objects.equals(workOrderEntity.getStatus(), WorkOrderStatusEnum.FINISH.getCode())) {
                        noEditList.add(workOrderEntity);
                    }
                });
            }
            if(!noEditList.isEmpty()) {
                // 错误信息
                throw new XbbException(ProErrorCodeEnum.API_ERROR_500018, String.format(ProErrorCodeEnum.API_ERROR_500018.getMsg(), noEditList.size()));
            }
            WorkOrderUpdateBatchDTO workOrderUpdateBatchDTO = new WorkOrderUpdateBatchDTO();
            BeanUtil.copyProperties(workOrderEditAttrUpdateDTO, workOrderUpdateBatchDTO);
            List<WorkOrderUpdateDTO> workOrderUpdateList = new ArrayList<>();
            workOrderEditAttrUpdateDTO.getDataIdList().forEach((item) -> {
                WorkOrderUpdateDTO workOrderUpdateDTO = new WorkOrderUpdateDTO();
                workOrderUpdateDTO.setId(item);
                JSONObject data = ProSaveHelp.getBatchUpdateData(workOrderEditAttrUpdateDTO.getFieldEditedList());
                workOrderUpdateDTO.setData(data);
                workOrderUpdateList.add(workOrderUpdateDTO);
            });

            if (!workOrderUpdateList.isEmpty()) {
                workOrderUpdateBatchDTO.setWorkOrderUpdateList(workOrderUpdateList);
                updateBatch(workOrderUpdateBatchDTO);
            }

            // 批量编辑日志
            List<String> updataItemList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<Long> dataIdList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (PaasFormDataEntityExt item : dataList) {
                dataIdList.add(item.getId());
                JSONObject data = item.getData();
                String serialNo = item.getSerialNo();
                String opObjectName = data.getString(WorkOrderEnum.NAME.getAttr());
                StringBuilder sb = new StringBuilder();
                opObjectName = opObjectName == null ? serialNo : sb.append(serialNo).append("（").append(opObjectName).append("）").toString();
                updataItemList.add(opObjectName);
            }
            String updataItem = StringUtils.join(updataItemList, "，");
            String userId = workOrderEditAttrUpdateDTO.getUserId();
            String corpid = workOrderEditAttrUpdateDTO.getCorpid();
            String loginUserName = workOrderEditAttrUpdateDTO.getLoginUserName();
            // 标签特殊处理
            Integer fieldType = workOrderEditAttrUpdateDTO.getFieldType();
            logHelp.analysisLabel(corpid, fieldType, isFieldDependence,workOrderEditAttrUpdateDTO.getLogFieldEditedList());

            String changedLogItemsStr = logHandleHelp.getChangedLogItemsStr(workOrderEditAttrUpdateDTO.getLogFieldEditedList());
            if(dataIdList.size() > 1 ){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_DATA_BATCH_ATTR), loginUserName, XbbRefTypeEnum.WORK_ORDER.getName(),
                        changedLogItemsStr, dataIdList.size());
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(XbbRefTypeEnum.WORK_ORDER.getName());
                infoArrPojo.setContent(updataItem);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, loginUserName, OperateModuleTypeEnum.WORK, OperateTypeEnum.EDIT,
                        "", "", memo, workOrderEditAttrUpdateDTO.getHttpHeader());
            } else if (Objects.equals(dataIdList.size(), 1)){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_DATA_ATTR), loginUserName, XbbRefTypeEnum.WORK_ORDER.getName(), updataItem,
                        changedLogItemsStr);
                mongoLogHelp.buildLog(corpid, userId, loginUserName, OperateModuleTypeEnum.WORK, OperateTypeEnum.EDIT,
                        dataIdList.get(0).toString(), updataItem, memo, workOrderEditAttrUpdateDTO.getHttpHeader());
            }


        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOG.error("WorkOrderServiceImpl.batchEditAttr 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return workOrderEditAttrUpdateVO;
    }

    @Override
    public WorkOrderUpdateBatchVO updateBatch(WorkOrderUpdateBatchDTO workOrderUpdateBatchDTO) throws XbbException {
        WorkOrderUpdateBatchVO workOrderUpdateBatchVO = new WorkOrderUpdateBatchVO();
        try {
            String corpid = workOrderUpdateBatchDTO.getCorpid();
            List<UpdateDataEntity> updateList = new ArrayList<>();
            List<WorkOrderUpdateDTO> workOrderUpdateList = workOrderUpdateBatchDTO.getWorkOrderUpdateList();
            if (Objects.nonNull(workOrderUpdateList) && !workOrderUpdateList.isEmpty()) {
                workOrderUpdateList.forEach((item) -> {
                    updateList.add(ExplainUtil.getUpdateData(item.getId(), item.getData(), corpid));
                });
            }
            if (!updateList.isEmpty()) {
                workOrderModel.updateBatch(updateList, corpid);
            }
        } catch (Exception e) {
            LOG.error("WorkOrderServiceImpl.updateBatch 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return workOrderUpdateBatchVO;
    }

    @Override
    public void formatLinkAddExplain(HandlerExplainInLinkItemDTO handlerExplainInLinkItemDTO) throws XbbException {
        JSONObject linkFormData = handlerExplainInLinkItemDTO.getLinkFormData();
        Long linkDataId = handlerExplainInLinkItemDTO.getLinkDataId();
        String corpid = handlerExplainInLinkItemDTO.getCorpid();
        List<FieldAttrEntity> explainList = handlerExplainInLinkItemDTO.getExplainList();
        FieldAttrEntity linkCustomerField = new FieldAttrEntity();
        FieldAttrEntity linkContactField = new FieldAttrEntity();
        FieldAttrEntity linkOpportunityField = new FieldAttrEntity();
        FieldAttrEntity linkContractField = new FieldAttrEntity();
        FieldAttrEntity linkProductField = new FieldAttrEntity();
        PaasFormDataEntityExt paasFormDataEntityExt = handlerExplainInLinkItemDTO.getPaasFormDataEntityExt();
        String serialNo = paasFormDataEntityExt.getSerialNo();
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            if (Objects.equals(fieldAttrEntity.getAttr(), WorkOrderEnum.LINK_CUSTOMER.getAttr())) {
                linkCustomerField = fieldAttrEntity;
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), WorkOrderEnum.LINK_CONTACT.getAttr())) {
                linkContactField = fieldAttrEntity;
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), WorkOrderEnum.LINK_OPPORTUNITY.getAttr())) {
                linkOpportunityField = fieldAttrEntity;
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), WorkOrderEnum.LINK_CONTRACT.getAttr())) {
                linkContractField = fieldAttrEntity;
            }
            if (Objects.equals(fieldAttrEntity.getAttr(), WorkOrderEnum.SPARE_PARTS.getAttr())) {
                linkProductField = fieldAttrEntity;
            }
        }

        LinkProductRelyEntity linkProductRelyEntity;
        // 源单解释
        Map<String, FieldAttrEntity> sourceExplainMap = null;
        // 当前表单解释
        Map<String, FieldAttrEntity> thisExplainMap = null;
        // 当前表单某个关联产品解释
        Map<String, FieldAttrEntity> subThisExplainMap = null;
        // 源单某个关联产品解释
        Map<String, FieldAttrEntity> subSourceExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        // 当前表单某个关联产品子字段与源单某个关联产品对应关系
        Map<String, String> thisToTarget = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(handlerExplainInLinkItemDTO.getLinkBusinessType());
        DefaultAttrPoJo productDefaultAttr = linkProductField.getDefaultAttr() == null ? new DefaultAttrPoJo() : linkProductField.getDefaultAttr();
        String defaultType = productDefaultAttr.getDefaultType();
        switch (redundantTemplateTypeEnum) {
            case CUSTOMER:
                String customerName = FastJsonHelper.getStringOrDefaultFromFormData(linkFormData, CustomerManagementEnum.NAME.getAttr(), "");
                linkCustomerField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkDataId, customerName));
                break;
            case SALES_OPPORTUNITY:
                if (Objects.isNull(serialNo)) {
                    String opportunityName = FastJsonHelper.getStringOrDefaultFromFormData(linkFormData, SalesOpportunityEnum.NAME.getAttr(), "");
                    linkOpportunityField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkDataId, opportunityName));
                } else {
                    linkOpportunityField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkDataId, serialNo));
                }
                JSONArray opportunityLinkCustomerArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(linkFormData, SalesOpportunityEnum.CUSTOMER_NAME.getAttr(), new JSONArray());
                linkCustomerField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(opportunityLinkCustomerArr));
                JSONArray opportunityLinkContactArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(linkFormData, SalesOpportunityEnum.CONTACT_NAME.getAttr(), new JSONArray());
                linkContactField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(opportunityLinkContactArr));
                //机会产品处理
//                JSONObject opportunityProductListObj = new JSONObject();
//                JSONArray opportunityProductArr = new JSONArray();
//                List<OpportunityProductEntity> opportunityProductEntityList = opportunityProductModel.getProductsByOppId(linkDataId, corpid);
//                for (OpportunityProductEntity entity : opportunityProductEntityList) {
//                    JSONObject product = new JSONObject();
//                    product.put(StringConstant.SAAS_LINK_BUSINESS_ID, entity.getProductId());
//                    product.put(StringConstant.NUM, entity.getProductNum());
//                    product.put(RelativeProductEnum.SALE_DISCOUNT.getSaasAttr(), entity.getDiscount());
//                    product.put(RelativeProductEnum.SALE_PRODUCT_PRICE.getSaasAttr(), entity.getPrice());
//                    opportunityProductArr.add(product);
//                }
//                opportunityProductListObj.put(StringConstant.PRODUCT_LIST, opportunityProductArr);
//                opportunityProductListObj.put(BusinessConstant.OTHERS, new JSONObject());
                JSONObject productData= new JSONObject();
                opportunityService.formatProduct4Show2(linkDataId,corpid,productData, UpdateDataTypeEnum.LINK_ADD);
                JSONArray productArray = formDataValidateProductHelp.otherProductToAnother(productData,linkProductField,WorkOrderEnum.SPARE_PARTS.getAttr(),SalesOpportunityEnum.PRODUCTS.getAttr(),corpid, handlerExplainInLinkItemDTO.getLoginUser(), handlerExplainInLinkItemDTO.getBusinessType(), handlerExplainInLinkItemDTO.getLinkBusinessType());
                // 关联产品自定义字段联动
                linkProductRelyEntity = linkProductRelyModel.getByAttrAndFormIdAndLinkFormId(corpid, WorkOrderEnum.SPARE_PARTS.getAttr(), handlerExplainInLinkItemDTO.getFormId(), handlerExplainInLinkItemDTO.getSourceFormId(), DelEnum.NORMAL.getDel());
                if (Objects.nonNull(defaultType) && Objects.equals(defaultType, DefaultTypeEnum.PRODUCT_DATA_RELY.getAlias()) && Objects.nonNull(linkProductRelyEntity)) {
                    // 源数据表单
                    PaasFormExplainEntity paasFormExplainEntity = proFormHelp.getExplainEntity(corpid, linkProductRelyEntity.getSourceFormId(), linkProductRelyEntity.getSourceBusinessType());
                    List<FieldAttrEntity> sourceExplainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                    sourceExplainMap = ExplainUtil.getExplainMapByList(sourceExplainList, null);
                    // 当前表单解释
                    PaasFormExplainEntity displayFormExplain = proFormHelp.getExplainEntity(corpid, linkProductRelyEntity.getFormId(), linkProductRelyEntity.getBusinessType());
                    thisExplainMap = ExplainUtil.getExplainMap(displayFormExplain.getExplains(), null);
                    subThisExplainMap = businessProductService.getProductRelyMap(WorkOrderEnum.SPARE_PARTS.getAttr(), linkProductRelyEntity, sourceExplainMap, thisExplainMap, subSourceExplainMap, thisToTarget);

                    UserAndDepartmentGetDTO userAndDepartmentGetDTO = new UserAndDepartmentGetDTO();
                    BeanUtil.copyProperties(handlerExplainInLinkItemDTO, userAndDepartmentGetDTO);
                    UserAndDepartmentGetVO userAndDepartmentGetVO = userHelp.getUserDepartmentMap(userAndDepartmentGetDTO);
                    Map<String, UserEntity> userMap = userAndDepartmentGetVO.getUserMap();
                    Map<String, DepartmentEntity> departmentMap = userAndDepartmentGetVO.getDepartmentMap();
                    for (Object o : productData.getJSONArray(SalesOpportunityEnum.PRODUCTS.getAttr())) {
                        JSONObject opportunityData = (JSONObject) o;
                        if (Objects.nonNull(opportunityData) && !thisToTarget.isEmpty()) {
                            ParseSingleRowDataDTO parseSingleRowDataDTO = new ParseSingleRowDataDTO();
                            parseSingleRowDataDTO.setDataJsonObject(opportunityData);
                            parseSingleRowDataDTO.setExplainMap(subSourceExplainMap);
                            parseSingleRowDataDTO.setUserMap(userMap);
                            parseSingleRowDataDTO.setDepartmentMap(departmentMap);
                            ParseSingleRowDataVO parseSingleRowDataVO = formDataUpdateGetAnalysisDataHelp.parseSingleRowData(parseSingleRowDataDTO);
                            if (Objects.isNull(parseSingleRowDataVO)) {
                                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PARSE_SINGLE_ROW_DATA_FAILED);
                            }
                            JSONObject result = parseSingleRowDataVO.getResult();
                            JSONObject thisData = businessProductService.formatThisFormData(subThisExplainMap, thisToTarget, result);
                            for (int i = 0; i < productArray.size(); i++) {
                                JSONObject jsonObject = productArray.getJSONObject(i);
                                if (Objects.equals(jsonObject.getLongValue(BusinessConstant.RELY_PRODUCT_SUB_ID), opportunityData.getLongValue(BusinessConstant.RELY_PRODUCT_SUB_ID))) {
                                    jsonObject.putAll(thisData);
                                    break;
                                }
                            }
                        }
                    }
                }
                linkProductField.setDefaultAttr(saasUpdateHelp.setDefaultValue(productArray));
                linkProductField.getDefaultAttr().setDefaultType(defaultType);

//                JSONObject opportunityDataList = new JSONObject();
//                opportunityDataList.put(WorkOrderEnum.SPARE_PARTS.getAttr(), opportunityProductListObj);
//                SaasAnalysisDataDTO opportunitySaasAnalysisDataDTO = new SaasAnalysisDataDTO();
//                opportunitySaasAnalysisDataDTO.setForProcess(true);
//                opportunitySaasAnalysisDataDTO.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
//                BeanUtil.copyProperties(handlerExplainInLinkItemDTO, opportunitySaasAnalysisDataDTO);
//                formatProduct4Show(opportunityDataList, opportunitySaasAnalysisDataDTO);
//                JSONObject opportunityProducts = opportunityDataList.getJSONObject(WorkOrderEnum.SPARE_PARTS.getAttr());
//                linkProductField.setDefaultAttr(saasUpdateHelp.setDefaultValue(opportunityProducts));

                break;
            case CONTRACT:
                if (Objects.isNull(serialNo)) {
                    String contractName = FastJsonHelper.getStringOrDefaultFromFormData(linkFormData, ContractEnum.NAME.getAttr(), "");
                    linkContractField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkDataId, contractName));
                } else {
                    linkContractField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkDataId, serialNo));
                }
                JSONArray contractCustomerArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(linkFormData, ContractEnum.LINK_CUSTOMER.getAttr(), new JSONArray());
                linkCustomerField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(contractCustomerArr));
                JSONArray contractContactArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(linkFormData, ContractEnum.LINK_CONTACT.getAttr(), new JSONArray());
                linkContactField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(contractContactArr));
                JSONArray contractOpportunityArr = FastJsonHelper.getJsonArrOrDefaultFromFormData(linkFormData, ContractEnum.LINK_OPPORTUNITY.getAttr(), new JSONArray());
                linkOpportunityField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(contractOpportunityArr));
                //合同产品处理
//                JSONObject contractProductListObj = new JSONObject();
//                JSONArray contractProductArr = new JSONArray();
//                List<ContractProductEntity> contractProductEntityList = contractProductModel.getProductsByConId(linkDataId, corpid);
//                for (ContractProductEntity entity : contractProductEntityList) {
//                    JSONObject product = new JSONObject();
//                    product.put(StringConstant.SAAS_LINK_BUSINESS_ID, entity.getProductId());
//                    product.put(StringConstant.NUM,  entity.getProductNum());
//                    contractProductArr.add(product);
//                }
//                contractProductListObj.put(StringConstant.PRODUCT_LIST, contractProductArr);
//                contractProductListObj.put(BusinessConstant.OTHERS, new JSONObject());
//                JSONObject contractDataList = new JSONObject();
//                contractDataList.put(WorkOrderEnum.SPARE_PARTS.getAttr(), contractProductListObj);
//                SaasAnalysisDataDTO contractSaasAnalysisDataDTO = new SaasAnalysisDataDTO();
//                contractSaasAnalysisDataDTO.setForProcess(true);
//                contractSaasAnalysisDataDTO.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
//                BeanUtil.copyProperties(handlerExplainInLinkItemDTO, contractSaasAnalysisDataDTO);
//                formatProduct4Show(contractDataList, contractSaasAnalysisDataDTO);
//                JSONObject contractProducts = contractDataList.getJSONObject(WorkOrderEnum.SPARE_PARTS.getAttr());
//                linkProductField.setDefaultAttr(saasUpdateHelp.setDefaultValue(contractProducts));
                productData= new JSONObject();
                contractModel.formatProduct4Show2(linkDataId,corpid,productData, UpdateDataTypeEnum.LINK_ADD);
                productArray = formDataValidateProductHelp.otherProductToAnother(productData,linkProductField,WorkOrderEnum.SPARE_PARTS.getAttr(),ContractEnum.PRODUCT.getAttr(),corpid, handlerExplainInLinkItemDTO.getLoginUser(), handlerExplainInLinkItemDTO.getBusinessType(), handlerExplainInLinkItemDTO.getLinkBusinessType());
                // 关联产品自定义字段联动
                linkProductRelyEntity = linkProductRelyModel.getByAttrAndFormIdAndLinkFormId(corpid, WorkOrderEnum.SPARE_PARTS.getAttr(), handlerExplainInLinkItemDTO.getFormId(), handlerExplainInLinkItemDTO.getSourceFormId(), DelEnum.NORMAL.getDel());
                if (Objects.nonNull(defaultType) && Objects.equals(defaultType, DefaultTypeEnum.PRODUCT_DATA_RELY.getAlias()) && Objects.nonNull(linkProductRelyEntity)) {
                    // 源数据表单
                    PaasFormExplainEntity paasFormExplainEntity = proFormHelp.getExplainEntity(corpid, linkProductRelyEntity.getSourceFormId(), linkProductRelyEntity.getSourceBusinessType());
                    List<FieldAttrEntity> sourceExplainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                    sourceExplainMap = ExplainUtil.getExplainMapByList(sourceExplainList, null);
                    // 当前表单解释
                    PaasFormExplainEntity displayFormExplain = proFormHelp.getExplainEntity(corpid, linkProductRelyEntity.getFormId(), linkProductRelyEntity.getBusinessType());
                    thisExplainMap = ExplainUtil.getExplainMap(displayFormExplain.getExplains(), null);
                    subThisExplainMap = businessProductService.getProductRelyMap(WorkOrderEnum.SPARE_PARTS.getAttr(), linkProductRelyEntity, sourceExplainMap, thisExplainMap, subSourceExplainMap, thisToTarget);
                    UserAndDepartmentGetDTO userAndDepartmentGetDTO = new UserAndDepartmentGetDTO();
                    BeanUtil.copyProperties(handlerExplainInLinkItemDTO, userAndDepartmentGetDTO);
                    UserAndDepartmentGetVO userAndDepartmentGetVO = userHelp.getUserDepartmentMap(userAndDepartmentGetDTO);
                    Map<String, UserEntity> userMap = userAndDepartmentGetVO.getUserMap();
                    Map<String, DepartmentEntity> departmentMap = userAndDepartmentGetVO.getDepartmentMap();
                    for (Object o : productData.getJSONArray(ContractEnum.PRODUCT.getAttr())) {
                        JSONObject contractData = (JSONObject) o;
                        if (Objects.nonNull(contractData) && !thisToTarget.isEmpty()) {
                            ParseSingleRowDataDTO parseSingleRowDataDTO = new ParseSingleRowDataDTO();
                            parseSingleRowDataDTO.setDataJsonObject(contractData);
                            parseSingleRowDataDTO.setExplainMap(subSourceExplainMap);
                            parseSingleRowDataDTO.setUserMap(userMap);
                            parseSingleRowDataDTO.setDepartmentMap(departmentMap);
                            ParseSingleRowDataVO parseSingleRowDataVO = formDataUpdateGetAnalysisDataHelp.parseSingleRowData(parseSingleRowDataDTO);
                            if (Objects.isNull(parseSingleRowDataVO)) {
                                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.PARSE_SINGLE_ROW_DATA_FAILED);
                            }
                            JSONObject result = parseSingleRowDataVO.getResult();
                            JSONObject thisData = businessProductService.formatThisFormData(subThisExplainMap, thisToTarget, result);
                            for (int i = 0; i < productArray.size(); i++) {
                                JSONObject jsonObject = productArray.getJSONObject(i);
                                if (Objects.equals(jsonObject.getLongValue(BusinessConstant.RELY_PRODUCT_SUB_ID), contractData.getLongValue(BusinessConstant.RELY_PRODUCT_SUB_ID))) {
                                    jsonObject.putAll(thisData);
                                    break;
                                }
                            }
                        }
                    }
                }
                linkProductField.setDefaultAttr(saasUpdateHelp.setDefaultValue(productArray));
                linkProductField.getDefaultAttr().setDefaultType(defaultType);
                break;
            default:
                throw new XbbException(TemplateErrorCodeEnum.API_ERROR_350006);
        }

    }

    @Override
    public void formatExportValue(List<PaasFormDataEntityExt> paasFormDataESList, FormDataListDTO formDataListDTO, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException {
        // 所有产品
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(ParameterConstant.CORPID, formDataListDTO.getCorpid());
        params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());


        Set<Long> workOrderSet = new HashSet<>();
        for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataESList) {
            workOrderSet.add(paasFormDataEntityExt.getId());
        }
        params.put("workOrderIdIn", workOrderSet);
        params.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
        List<WorkOrderProductEntity> workOrderProductEntityList = workOrderProductModel.findEntitys(params);
        Set<Long> productSet = new HashSet<>();
        workOrderProductEntityList.forEach(item -> productSet.add(item.getProductId()));
        if (productSet.isEmpty()){
            return;
        }
        params.clear();
        params.put(ParameterConstant.CORPID, formDataListDTO.getCorpid());
        params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        params.put("productIdIn",productSet);
        List<ProductEntityExt> productList = productModel.findEntitys(params);
        Map<Long, ProductEntityExt> productMap = new HashMap<>();
        productList.forEach(item -> productMap.put(item.getId(), item));

        Map<Long, List<WorkOrderProductEntity>> workOrderProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        workOrderProductEntityList.forEach(item -> {
            if (workOrderProductMap.containsKey(item.getWorkOrderId())) {
                workOrderProductMap.get(item.getWorkOrderId()).add(item);
            } else {
                List<WorkOrderProductEntity> workOrderProductList = new ArrayList<>();
                workOrderProductList.add(item);
                workOrderProductMap.put(item.getWorkOrderId(), workOrderProductList);
            }
        });

        Map<String, MultiUnitItemPoJo> groupBaseUnitStringMap = relativeProductHelp.getGroupBaseUnitStringMap(formDataListDTO.getCorpid());

        // 暂时只处理产品
        for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataESList) {
            Long supplierId = paasFormDataEntityExt.getId();
            JSONObject formDataObj = paasFormDataEntityExt.getData();
            if (workOrderProductMap.containsKey(supplierId)) {
                List<WorkOrderProductEntity> workOrderProductList = workOrderProductMap.get(supplierId);
                JSONArray productArray = new JSONArray();
                for (WorkOrderProductEntity entity : workOrderProductList) {
                    if (productMap.containsKey(entity.getProductId())) {
                        JSONObject productItemObj = entity.getData();
                        if (Objects.isNull(productItemObj)){
                            productItemObj = new JSONObject();
                        }
                        JSONObject productData =  productMap.get(entity.getProductId()).getData();
                        productItemObj.put(SelectProductEnum.PRODUCT_NAME.getAttr(), productData.get(ProductEnum.NAME.getAttr()));
                        productItemObj.put(SelectProductEnum.PRODUCT_NO.getAttr(), productMap.get(entity.getProductId()).getSerialNo());
                        String productSpecification = Objects.equals(productData.getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr()), "{}") ? "" : productData.getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr());
                        productItemObj.put(SelectProductEnum.SPECIFICATION.getAttr(), productSpecification);
                        productItemObj.put(SelectProductEnum.NUM.getAttr(), entity.getProductNum());
                        productItemObj.put(SelectProductEnum.BARCODE.getAttr(),productData.get(ProductEnum.BARCODE.getAttr()));
                        productItemObj.put(SelectProductEnum.OUTSTOCK_NUM.getAttr(), entity.getOutstockNum());
                        productItemObj.put(SelectProductEnum.WAIT_OUTSTOCK_NUM.getAttr(), Arith.sub(entity.getProductNum(), entity.getOutstockNum()));
                        productItemObj.put(SelectProductEnum.UNIT.getAttr(), productData.get(ProductEnum.UNIT.getAttr()));
                        productItemObj.put(ProductEnum.ENABLE_MULTI_UNIT.getAttr(), productData.getIntValue(ProductEnum.ENABLE_MULTI_UNIT.getAttr()));
                        if (Objects.nonNull(entity.getData()) && Objects.nonNull(entity.getData().get(ProductEnum.UNIT.getAttr())) && !StringUtil.isEmpty(entity.getData().get(ProductEnum.UNIT.getAttr()).toString())){
                            if (StringUtil.isDigital(entity.getData().get(ProductEnum.UNIT.getAttr()).toString())){
                                Long unitId = Long.valueOf(entity.getData().get(ProductEnum.UNIT.getAttr()).toString());
                                if (unitId > ProductConstant.MAX_SINGLE_UNIT_VALUE) {
                                    entity.getData().put(ProductEnum.ENABLE_MULTI_UNIT.getSaasAttr(), BasicConstant.ONE);
                                }
                            }
                        }
                        //基本单位时直接塞入productUnit
                        if (Objects.isNull(entity.getBusinessUnit())){
                            if (Objects.equals(productItemObj.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getAttr()), BasicConstant.ONE)){
                                productItemObj.put(ProductEnum.UNIT.getAttr(), groupBaseUnitStringMap.getOrDefault(productItemObj.getString(ProductEnum.UNIT.getAttr()), new MultiUnitItemPoJo()).getBaseValue());
                                entity.setProductUnit(productItemObj.getString(ProductEnum.UNIT.getAttr()));
                            }
                            productItemObj.put(SelectProductEnum.NUM.getAttr(), entity.getProductNum());
                        }else {
                            productItemObj.put(ProductEnum.UNIT.getAttr(), entity.getBusinessUnit());
                            productItemObj.put(SelectProductEnum.NUM.getAttr(), entity.getBusinessNum());
                            productItemObj.put(SelectProductEnum.OUTSTOCK_NUM.getAttr(), Arith.div(entity.getOutstockNum(), entity.getRate()));
                            productItemObj.put(SelectProductEnum.WAIT_OUTSTOCK_NUM.getAttr(), Arith.sub(entity.getBusinessNum(), Arith.div(entity.getOutstockNum(), entity.getRate())));
                        }

                        if(Objects.equals(productItemObj.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getAttr()), BasicConstant.ONE)){
                            productItemObj.put(SelectProductEnum.BASIC_UNIT.getAttr(), entity.getProductUnit());
                            productItemObj.put(SelectProductEnum.BASIC_UNIT_NUM.getAttr(),  entity.getProductNum());
                        }else {
                            productItemObj.put(SelectProductEnum.BASIC_UNIT.getAttr(), "");
                            productItemObj.put(SelectProductEnum.BASIC_UNIT_NUM.getAttr(), "");
                        }
                        productArray.add(productItemObj);
                    }
                }
                formDataObj.put(WorkOrderEnum.SPARE_PARTS.getAttr(), productArray);
            } else {
                formDataObj.remove(WorkOrderEnum.SPARE_PARTS.getAttr());
            }
        }
    }

    @Override
    public FormDataAddDTO formatExcelValue(ImportFormDataDTO importFormDataDTO, List<CellTitlePojo> titlePojoList, RowGroupPojo rowGroupPojo, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException {
        return null;
    }

    @Override
    public void dataConsistencyUpdateCustomer(String corpid, Long customerId, String customerName) throws XbbException {
        try {
            BoolQueryBuilder filter = boolQuery()
                    .filter(termQuery("corpid.keyword", corpid))
                    .filter(termQuery("del", 0))
                    .filter(termQuery(WorkOrderEnum.getEsAttr4Keyword(WorkOrderEnum.LINK_CUSTOMER), customerId));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(FieldTypeEnum.DATAID.getAlias());
            List<PaasFormDataEntityExt> esEntities = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_WORK_ORDER, filter, PaasFormDataEntityExt.class, fieldList);
            Set<Long> ids = new HashSet<>();
            for (PaasFormDataEntityExt esEntity : esEntities) {
                ids.add(esEntity.getDataId());
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("idIn", ids);
            param.put("del", 0);
            List<WorkOrderEntity> workOrderEntityExtList = workOrderModel.findEntitys(param);

            if (Objects.nonNull(workOrderEntityExtList) && !workOrderEntityExtList.isEmpty()) {
                List<WorkOrderUpdateDTO> workOrderUpdateDTOList = new ArrayList<>();
                for (WorkOrderEntity entity : workOrderEntityExtList) {
                    WorkOrderUpdateDTO workOrderUpdateDTO = new WorkOrderUpdateDTO();
                    workOrderUpdateDTO.setId(entity.getId());
                    JSONObject data = new JSONObject();
                    data.put(WorkOrderEnum.LINK_CUSTOMER_HIDE.getAttr(), customerName);
                    workOrderUpdateDTO.setData(data);
                    workOrderUpdateDTOList.add(workOrderUpdateDTO);
                }
                WorkOrderUpdateBatchDTO workOrderUpdateBatchDTO = new WorkOrderUpdateBatchDTO();
                workOrderUpdateBatchDTO.setCorpid(corpid);
                workOrderUpdateBatchDTO.setWorkOrderUpdateList(workOrderUpdateDTOList);
                updateBatch(workOrderUpdateBatchDTO);
            }

        } catch (Exception e) {
            LOG.error("WorkOrderServiceImpl.dataConsistencyUpdateCustomer 出错， corpid=" + corpid + "  customerId=" + customerId + " customerName=" + customerName, e);
        }
    }

    @Override
    public void restoreOutboundAndStatus(WorkOrderRestoreOutboundDTO workOrderRestoreOutboundDTO) throws XbbException {
        try {
            if (Objects.isNull(workOrderRestoreOutboundDTO) || Objects.isNull(workOrderRestoreOutboundDTO.getWorkOrderOutstockList()) || workOrderRestoreOutboundDTO.getWorkOrderOutstockList().isEmpty()) {
                return;
            }
            // 删除的工单出库单id列表
            List<Long> delWorkOrderOutstockIdList = new ArrayList<>();
            List<Long> workOrderIdList = new ArrayList<>();
            workOrderRestoreOutboundDTO.getWorkOrderOutstockList().forEach(item -> {
                JSONObject data = item.getData();
                if (Objects.nonNull(data) && Objects.nonNull(data.get(OutstockEnum.REF_ID.getAttr())) && !Objects.equals(data.getLong(OutstockEnum.REF_ID.getAttr()), 0D)) {
                    Long workOrderId = data.getLong(OutstockEnum.REF_ID.getAttr());
                    workOrderIdList.add(workOrderId);
                    delWorkOrderOutstockIdList.add(item.getId());
                }
            });

            String corpid = workOrderRestoreOutboundDTO.getCorpid();
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("corpid", corpid);
            params.put("del", DelEnum.NORMAL.getDel());
            params.put("idIn", workOrderIdList);
            List<WorkOrderEntity> workOrderEntityList = workOrderModel.findEntitysWithoutSub(params);

            List<Long> delOutstockIdList = workOrderRestoreOutboundDTO.getDelOutstockIdList();
            WorkOrderOutstockDeleteVO workOrderOutstockDeleteVO = workOrderProductService.getSurplusProductBatch(corpid, workOrderIdList, delOutstockIdList);
            Map<Long, List<WorkOrderProductEntity>> workOrderLeftUnOutstockProductMap = workOrderOutstockDeleteVO.getWorkOrderLeftUnOutstockProductMap();

            for (WorkOrderEntity workOrderEntity : workOrderEntityList) {
                List<WorkOrderProductEntity> surplusProduct = workOrderLeftUnOutstockProductMap.get(workOrderEntity.getId());
                if (surplusProduct.isEmpty()) {
                    workOrderEntity.setAllOutbound(1);
                } else {
                    workOrderEntity.setAllOutbound(0);
                }
            }

            List<WorkOrderProductEntity> updateList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long,Double> workOrderOutstockNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<OutstockProductEntity> workOrderProductList = workOrderRestoreOutboundDTO.getWorkOrderProductList();
            for (OutstockProductEntity entity : workOrderProductList) {
                // WorkOrderRestoreOutboundDTO返回的出库产品是所有的出库产品，需要从中筛选出工单出库产品
                if (delWorkOrderOutstockIdList.contains(entity.getOutWarehouseId())) {
                    if (Objects.nonNull(entity.getRefProductId())) {
                        double outstockNum = workOrderOutstockNumMap.getOrDefault(entity.getRefProductId(), 0D);
                        outstockNum = Arith.add(outstockNum, entity.getProductNum());
                        workOrderOutstockNumMap.put(entity.getRefProductId(), outstockNum);
                    }else {
                        double outstockNum = workOrderOutstockNumMap.getOrDefault(entity.getId(), 0D);
                        outstockNum = Arith.add(outstockNum, entity.getProductNum());
                        workOrderOutstockNumMap.put(entity.getId(), outstockNum);
                    }
                }
            }
            List<WorkOrderProductEntity> workOrderProductEntityList = workOrderOutstockDeleteVO.getWorkOrderProductList();
            Set<Long> shipFlagSet = new HashSet<>(workOrderEntityList.size());
            for (WorkOrderProductEntity entity : workOrderProductEntityList) {
                if (workOrderOutstockNumMap.containsKey(entity.getId())){
                    double outstockNum = Math.max(Arith.sub(entity.getOutstockNum(), workOrderOutstockNumMap.get(entity.getId())), 0D);
                    entity.setOutstockNum(outstockNum);
                    updateList.add(entity);
                    if (outstockNum != 0) { // 部分出库
                        shipFlagSet.add(entity.getWorkOrderId());
                    }
                }else if (workOrderOutstockNumMap.containsKey(entity.getProductId())){
                    Double outstockNum = entity.getOutstockNum();
                    Double amendNum = workOrderOutstockNumMap.get(entity.getProductId());
                    double outNum = Arith.sub(amendNum, outstockNum);
                    if (outNum > 0) {
                        outstockNum = 0D;
                        workOrderOutstockNumMap.put(entity.getProductId(), outNum);
                    }else {
                        outstockNum = Arith.sub(outstockNum, amendNum);
                        workOrderOutstockNumMap.remove(entity.getProductId());
                    }
                    entity.setOutstockNum(outstockNum);
                    entity.setUpdateTime(DateTimeUtil.getInt());
                    updateList.add(entity);
                }
            }
            // 修改出库状态
            workOrderEntityList.forEach(i -> {
                JSONObject data = i.getData();
                if (shipFlagSet.contains(i.getId())) {
                    data.put(WorkOrderEnum.SHIP_STATUS.getAttr(), WorkOrderShipStatusEnum.DELIVERED.getCode());
                } else {
                    data.put(WorkOrderEnum.SHIP_STATUS.getAttr(), WorkOrderShipStatusEnum.UNSHIPPED.getCode());
                }
            });

            workOrderModel.updateBatchList(workOrderEntityList, corpid);
            if (!updateList.isEmpty()) {
                workOrderProductModel.updateBatch(updateList, corpid);
            }
        } catch (XbbException e) {
            LOG.error("WorkOrderService.restoreOutboundAndStatus 报错：" , e);
            throw e;
        } catch (Exception e) {
            LOG.error("WorkOrderService.restoreOutboundAndStatus 报错：" , e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
    }

    @Override
    public Integer judgeWorkOrderAllOutBound(Long outstockId, Long workOrderId, String corpid, List<ProductSavePojo> productSavePojoList) throws XbbException {
        return workOrderHelp.judgeWorkOrderAllOutBound(outstockId, workOrderId, corpid, productSavePojoList);
    }

    @Override
    public ProductSummaryVO summaryProductList(BusinessProductListDTO businessProductListDTO) throws XbbException {
        // 获取参数
        String corpid = businessProductListDTO.getCorpid();
        Long dataId = businessProductListDTO.getDataId();

        WorkOrderEntity workOrderEntity = workOrderModel.getByKey(dataId, corpid);
        if (Objects.isNull(workOrderEntity) || Objects.equals(workOrderEntity.getDel(), DelEnum.DELETE.getDel())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404);
        }
        Map<String, Object> modelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        modelMap.put(ParameterConstant.CORPID, corpid);
        modelMap.put("workOrderId", dataId);
        modelMap.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        modelMap.put("columns", "product_num,business_num");
        List<WorkOrderProductEntity> workOrderProductEntities = workOrderProductModel.findEntitys(modelMap);

        ProductSummaryVO businessProductListVO = new ProductSummaryVO();

        Double num = 0D;
        for (WorkOrderProductEntity productEntity : workOrderProductEntities) {
            Double productNum = productEntity.getProductNum() != null ? productEntity.getProductNum(): 0D;
            num = Arith.add(num, productEntity.getBusinessNum() == null ? productNum : productEntity.getBusinessNum());
        }
        Integer productSize = workOrderProductEntities.size();
        //若是不可见的情况产品详情也不予回显
        Long formId = workOrderEntity.getFormId();
        //获取解释
        WorkOrderExplainEntity workOrderExplainEntity = workOrderExplainModel.getByFormId(formId, corpid);
        if (workOrderExplainEntity == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        List<FieldAttrEntity> explainList = JSONArray.parseArray(workOrderExplainEntity.getExplains(), FieldAttrEntity.class);
        Map<String, FieldAttrEntity> explainMap = new LinkedHashMap<>(explainList.size());
        // 将字段放入字段容器
        for (FieldAttrEntity fieldAttrEntity : explainList) {
            explainMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
        }
        //协同团队
        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        userTeamService.getUserIdMap(Collections.singletonList(dataId), corpid, XbbRefTypeEnum.WORK_ORDER.getCode(), false, mainUserMap, coUserMap);
        // 当前数据的创建人、负责人、协同人、当前操作人
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        handlerExplainDTO.setOwnerId(mainUserMap.get(dataId));
        handlerExplainDTO.setCoUserId(coUserMap.get(dataId));
        handlerExplainDTO.setCreatorId(workOrderEntity.getCreatorId());
        handlerExplainDTO.setUserId(businessProductListDTO.getUserId());
        handlerExplainDTO.setLoginUser(businessProductListDTO.getLoginUser());
        //实施备件不可见时不予回显
        if (!commonHelp.attrCanSee(WorkOrderEnum.SPARE_PARTS.getAttr(), explainMap, handlerExplainDTO)) {
            num = 0D;
            productSize = 0;
        }
        String summaryInfo = String.format(I18nMessageUtil.getMessage(StringConstant.PRODUCTS_TYPE_NUM), productSize, Arith.doubleToBigDecimal(num));
        businessProductListVO.setSummaryInfo(summaryInfo);
        if (CollectionUtils.isNotEmpty(workOrderProductEntities) && (Objects.isNull(workOrderEntity.getAllOutbound()) || Objects.equals(workOrderEntity.getAllOutbound(), 0)) && businessProductListDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.WORK_ORDER_OUTSTOCK_ADD.getAlias())) {
            ButtonPojo buttonPojo = new ButtonPojo();
            buttonPojo.setAttr("exWarehouse");
            buttonPojo.setValue(I18nMessageUtil.getMessage(I18nStringConstant.ONE_CLICK_DELIVERY));
            buttonPojo.setLinkBusinessType(XbbRefTypeEnum.WORK_ORDER_OUTSTOCK.getCode());
            List<ButtonPojo> topRightButton = new ArrayList<>();
            topRightButton.add(buttonPojo);
            businessProductListVO.setTopRightButton(topRightButton);
        }
        return businessProductListVO;
    }

    @Override
    public WorkOrderUpdateByBusinessRuleVO updateBatchByBusinessRule(WorkOrderUpdateByBusinessRuleDTO workOrderUpdateByBusinessRuleDTO) throws XbbException {
        WorkOrderUpdateByBusinessRuleVO workOrderUpdateByBusinessRuleVO = new WorkOrderUpdateByBusinessRuleVO();
        try {
            String corpid = workOrderUpdateByBusinessRuleDTO.getCorpid();
            List<PaasFormDataEntityExt> formDataList = workOrderUpdateByBusinessRuleDTO.getFormDataList();
            List<UpdateDataEntity> updateList = ExplainUtil.getUpdateValueByBusinessRule(formDataList, corpid, workOrderUpdateByBusinessRuleDTO.getOperations());

            if (!updateList.isEmpty()) {
                workOrderModel.updateBatch(updateList, corpid);
                RuleBusinessLogDTO businessLogDTO = new RuleBusinessLogDTO();
                BeanUtil.copyProperties(workOrderUpdateByBusinessRuleDTO, businessLogDTO);
                businessLogDTO.setFormDataList(formDataList);
                ruleBusinessLogger.writeLog(businessLogDTO, updateList);
            }
        } catch (Exception e) {
            LOG.error("workOrderService.updateFormDataByBusinessRule根据业务规则更新数据出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return workOrderUpdateByBusinessRuleVO;
    }

    @Override
    public PagingProductVO getPagingProduct(PagingProductDTO pagingProductDTO) throws XbbException {
        PagingProductVO pagingProductVO = new PagingProductVO();
        Map<String, Object> modelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        modelMap.put(ParameterConstant.CORPID, pagingProductDTO.getCorpid());
        modelMap.put(ParameterConstant.WORKORDER_ID, pagingProductDTO.getDataId());
        modelMap.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        modelMap.put(ParameterConstant.PAGE,  pagingProductDTO.getPage());
        modelMap.put(ParameterConstant.ORDER_BY_STR, BasicConstant.SORT);
        PageHelper pageHelper = PageHelperUtil.getPageHelper(modelMap, workOrderProductModel, pagingProductDTO.getPageSize());
        List<WorkOrderProductEntity> workOrderProductEntityList = (List<WorkOrderProductEntity>) PageHelperUtil.getEntityList(modelMap, pageHelper, workOrderProductModel);
        if (pagingProductDTO.getUpdateDataTypeEnum().isDetail()) {
            DetailProductVO detailProductVO = formatProduct4DetailShow(workOrderProductEntityList, pagingProductDTO);
            pagingProductVO.setProductDataArr(detailProductVO.getProductDataArr());
        }
        pagingProductVO.setPageHelper(pageHelper);
        return pagingProductVO;
    }

    public DetailProductVO formatProduct4DetailShow(List<WorkOrderProductEntity> workOrderProductEntityList, PagingProductDTO pagingProductDTO) throws XbbException{
        DetailProductVO detailProductVO = new DetailProductVO();
        Set<Long> productIds = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (WorkOrderProductEntity workOrderProductEntity : workOrderProductEntityList) {
            productIds.add(workOrderProductEntity.getProductId());
        }
        JSONArray productArray = new JSONArray();
        for (WorkOrderProductEntity workOrderProductEntity : workOrderProductEntityList) {
            JSONObject json = workOrderProductEntity.getData() == null ? new JSONObject() : workOrderProductEntity.getData();
            if (Objects.nonNull(workOrderProductEntity.getBusinessUnit())) {
                workOrderProductEntity.setProductNum(Arith.div(workOrderProductEntity.getProductNum(), workOrderProductEntity.getRate()));
                workOrderProductEntity.setOutstockNum(Arith.div(workOrderProductEntity.getOutstockNum(), workOrderProductEntity.getRate()));
                workOrderProductEntity.setProductUnit(workOrderProductEntity.getBusinessUnit().toString());
                JSONObject priceData = workOrderProductEntity.getPriceData();
                if (Objects.nonNull(priceData) && !priceData.isEmpty()) {
                    workOrderProductEntity.setProductPrice(priceData.getDouble(SelectProductEnum.PRICE.getAttr()));
                }
            }
            for (WorkOrderProductEnum workOrderProductEnum : WorkOrderProductEnum.values()) {
                if (!UpdateDataTypeEnum.DETAIL.formatShow(workOrderProductEnum.getShowType())) {
                    continue;
                }
                String attr = workOrderProductEnum.getAttr();
                switch (workOrderProductEnum) {
                    case PRODUCT:
                        json.put(attr, workOrderProductEntity.getProductId());
                        break;
                    case PRICE:
                        json.put(attr, workOrderProductEntity.getProductPrice());
                        break;
                    case NUM:
                        json.put(attr, workOrderProductEntity.getProductNum());
                        break;
                    case MEMO:
                        json.put(attr, workOrderProductEntity.getMemo());
                        break;
                    case UNIT:
                        json.put(attr, workOrderProductEntity.getProductUnit());
                        break;
                    case OUTSTOCK_NUM:
                        json.put(attr,workOrderProductEntity.getOutstockNum());
                        break;
                    case WAIT_OUTSTOCK_NUM:
                        json.put(attr,Arith.sub(workOrderProductEntity.getProductNum(),workOrderProductEntity.getOutstockNum()));
                        break;
                    default:
                        break;
                }
            }
            json.put("refId",workOrderProductEntity.getId());
            json.put(BusinessConstant.PRODUCT_SUB_ID, workOrderProductEntity.getId());
            productArray.add(json);
        }
        detailProductVO.setProductDataArr(productArray);
        return detailProductVO;
    }

    @Override
    public void formatProduct4Show2(Long dataId, String corpid, JSONObject data, UpdateDataTypeEnum updateDataTypeEnum) throws XbbException {
        workOrderModel.formatProduct4Show2(dataId, corpid, data, updateDataTypeEnum);
    }

    @Override
    public JSONObject formatSingleProduct(WorkOrderProductEntity workOrderProductEntity) {
        return workOrderModel.formatSingleProduct(workOrderProductEntity);
    }

    @Override
    public void dataConsistencyUpdateContract(String corpid, Long contractId, String serialNo) {
        try {
            BoolQueryBuilder filter = boolQuery()
                    .filter(termQuery("corpid.keyword", corpid))
                    .filter(termQuery("del", 0))
                    .filter(termQuery(WorkOrderEnum.getEsAttr4Keyword(WorkOrderEnum.LINK_CONTRACT), contractId));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(FieldTypeEnum.DATAID.getAlias());
            List<PaasFormDataEntityExt> esEntities = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_WORK_ORDER, filter, PaasFormDataEntityExt.class, fieldList);
            Set<Long> ids = new HashSet<>();
            for (PaasFormDataEntityExt esEntity : esEntities) {
                ids.add(esEntity.getDataId());
            }
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("idIn", ids);
            param.put("del", 0);
            List<WorkOrderEntity> workOrderEntityExtList = workOrderModel.findEntitys(param);

            if (Objects.nonNull(workOrderEntityExtList) && !workOrderEntityExtList.isEmpty()) {
                List<WorkOrderUpdateDTO> workOrderUpdateDTOList = new ArrayList<>();
                for (WorkOrderEntity entity : workOrderEntityExtList) {
                    WorkOrderUpdateDTO workOrderUpdateDTO = new WorkOrderUpdateDTO();
                    workOrderUpdateDTO.setId(entity.getId());
                    JSONObject data = new JSONObject();
                    data.put(WorkOrderEnum.LINK_CONTRACT_HIDE.getAttr(), serialNo);
                    workOrderUpdateDTO.setData(data);
                    workOrderUpdateDTOList.add(workOrderUpdateDTO);
                }
                WorkOrderUpdateBatchDTO workOrderUpdateBatchDTO = new WorkOrderUpdateBatchDTO();
                workOrderUpdateBatchDTO.setCorpid(corpid);
                workOrderUpdateBatchDTO.setWorkOrderUpdateList(workOrderUpdateDTOList);
                updateBatch(workOrderUpdateBatchDTO);
            }

        } catch (Exception e) {
            LOG.error("WorkOrderServiceImpl.dataConsistencyUpdateContract 出错， corpid=" + corpid + "  contractId=" + contractId + " serialNo=" + serialNo, e);
        }
    }

    @Override
    public void updateBatchLabelAttr(AddLabelDTO addLabelDTO, List<PaasFormDataEntityExt> addBatchList, Boolean addOrDelete) throws XbbException {
        WorkOrderUpdateBatchDTO workOrderUpdateBatchDTO = new WorkOrderUpdateBatchDTO();
        BeanUtil.copyProperties(addLabelDTO, workOrderUpdateBatchDTO);
        List<WorkOrderUpdateDTO> workOrderList = new ArrayList<>();
        addBatchList.forEach(item->{
            WorkOrderUpdateDTO workOrderUpdateDTO = new WorkOrderUpdateDTO();
            workOrderUpdateDTO.setData(item.getData());
            workOrderUpdateDTO.setId(item.getId());
            workOrderList.add(workOrderUpdateDTO);
        });
        workOrderUpdateBatchDTO.setWorkOrderUpdateList(workOrderList);
        updateBatch(workOrderUpdateBatchDTO);

    }

    @Override
    public void afterSaveForWorkFlow(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        //获取data
        WorkOrderEntity workOrderEntity = saasFormSaveDTO.getNewWorkOrderEntity();
        JSONObject data = saasFormSaveDTO.getNewData();
        String corpid = saasFormSaveDTO.getCorpid();
        Long workOrderId = workOrderEntity.getId();
        //产品保存
        if (saasFormSaveDTO.getIsNew() || saasFormSaveDTO.getSaasNeedRedundantAttrPoJo().getAttrCanSee(WorkOrderEnum.SPARE_PARTS.getAttr())) {
            JSONArray productJsonArray = data.getJSONArray(WorkOrderEnum.SPARE_PARTS.getAttr());
            saveProduct(productJsonArray, corpid, workOrderId,workOrderEntity.getFormId());
        }
        if (!Objects.equals(saasFormSaveDTO.getFromOuterLink(), 1)) {
            // 外链没有团队字段，所以外链保存是不需要处理团队字段的
            //负责团队保存
            PaasFormDataEntity newPaasFormDataEntity = new PaasFormDataEntity();
            BeanUtil.copyProperties(workOrderEntity, newPaasFormDataEntity);
            if(saasFormSaveDTO.getIsNew()){
                saasFormSaveDTO.getSaasNeedRedundantAttrPoJo().getTeamAfterVerifyDTO().getAddMainUserMap().clear();
            }
            teamDataHelp.saveUserTeam(saasFormSaveDTO.getSaasNeedRedundantAttrPoJo(), workOrderId, newPaasFormDataEntity, saasFormSaveDTO.getIsImport(), true);
        }
    }


}
